使用实例类型对实例方法的方法引用
Method reference to instance method using instance type
我指的是 this 文章,其中指出我们可以使用两种方式引用实例方法:
使用实例
obj::instanceMethod
使用实例类型
ObjectType::instanceMethod
首先我用我的简单例子很容易验证:
class DummyConsumer
{
public void consume(String a)
{
System.out.println("Counsumed " + a);
}
}
DummyConsumer d = new DummyConsumer();
Consumer<String> c1 = d::consume; //method reference
Consumer<String> c2 = (s) -> d.consume(s); //lambda expression
c1.accept("s");
c2.accept("d");
但我无法对 ObjectType::instanceMethod
做同样的事情。该页面上给出的示例让我很困惑,如下所示:
class Shipment {
public double calculateWeight() { return 0d; }
}
public List<Double> calculateOnShipments(List<Shipment> l, Function<Shipment, Double> f) {
List<Double> results = new ArrayList<>();
for(Shipment s : l) {
results.add(f.apply(s));
}
return results;
}
calculateOnShipments(l, s -> s.calculateWeight()); //lambda expression
calculateOnShipments(l, Shipment::calculateWeight); //method reference
请注意上面最后一行的 Shipment::calculateWeight
。有人可以帮我用我的 Consumer 示例来模仿吗?
之所以可以在没有实例的情况下使用 ObjectType::instanceMethod
,是因为该方法引用表示接受 ObjectType
作为参数的方法,后跟 instanceMethod
的参数。
class A {
public void f(String s) {}
}
在这里,您可以将 A::f
视为代表这样的 "static" 方法:
public static void f(A a, String s) {}
因此在您的示例中,您需要一个 BiConsumer
来表示一个接受两个参数且不返回任何内容的方法:
BiConsumer<DummyConsumer, String> c = DummyConsumer::consume;
在Shipment
的情况下,Shipment::calculateWeight
代表一个"static"方法,像这样:
public static double calculateWeight(Shipment s) { ... }
这就是为什么Shipment::calculateWeight
可以用Function<Shipment, Double>
表示的原因。
所以一般来说,你只需要先弄清楚一个方法引用代表的是一个什么样的方法,然后找到一个代表这种方法的函数式接口就可以了。有时,您需要自己创建一个函数式界面!
我指的是 this 文章,其中指出我们可以使用两种方式引用实例方法:
使用实例
obj::instanceMethod
使用实例类型
ObjectType::instanceMethod
首先我用我的简单例子很容易验证:
class DummyConsumer
{
public void consume(String a)
{
System.out.println("Counsumed " + a);
}
}
DummyConsumer d = new DummyConsumer();
Consumer<String> c1 = d::consume; //method reference
Consumer<String> c2 = (s) -> d.consume(s); //lambda expression
c1.accept("s");
c2.accept("d");
但我无法对 ObjectType::instanceMethod
做同样的事情。该页面上给出的示例让我很困惑,如下所示:
class Shipment {
public double calculateWeight() { return 0d; }
}
public List<Double> calculateOnShipments(List<Shipment> l, Function<Shipment, Double> f) {
List<Double> results = new ArrayList<>();
for(Shipment s : l) {
results.add(f.apply(s));
}
return results;
}
calculateOnShipments(l, s -> s.calculateWeight()); //lambda expression
calculateOnShipments(l, Shipment::calculateWeight); //method reference
请注意上面最后一行的 Shipment::calculateWeight
。有人可以帮我用我的 Consumer 示例来模仿吗?
之所以可以在没有实例的情况下使用 ObjectType::instanceMethod
,是因为该方法引用表示接受 ObjectType
作为参数的方法,后跟 instanceMethod
的参数。
class A {
public void f(String s) {}
}
在这里,您可以将 A::f
视为代表这样的 "static" 方法:
public static void f(A a, String s) {}
因此在您的示例中,您需要一个 BiConsumer
来表示一个接受两个参数且不返回任何内容的方法:
BiConsumer<DummyConsumer, String> c = DummyConsumer::consume;
在Shipment
的情况下,Shipment::calculateWeight
代表一个"static"方法,像这样:
public static double calculateWeight(Shipment s) { ... }
这就是为什么Shipment::calculateWeight
可以用Function<Shipment, Double>
表示的原因。
所以一般来说,你只需要先弄清楚一个方法引用代表的是一个什么样的方法,然后找到一个代表这种方法的函数式接口就可以了。有时,您需要自己创建一个函数式界面!