我指的是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示例帮助我模仿吗?
答案 0 :(得分:0)
您似乎可以在没有实例的情况下使用ObjectType::instanceMethod
的原因是因为该方法引用表示接受ObjectType
作为参数,然后是instanceMethod
的参数的方法。
class A {
public void f(String s) {}
}
在这里,您可以想到A::f
代表着这样的“静态”方法:
public static void f(A a, String s) {}
因此在您的示例中,您需要一个BiConsumer
来表示一个接受两个参数并且不返回任何内容的方法:
BiConsumer<DummyConsumer, String> c = DummyConsumer::consume;
在Shipment
情况下,Shipment::calculateWeight
表示这样的“静态”方法:
public static double calculateWeight(Shipment s) { ... }
这就是Shipment::calculateWeight
可以用Function<Shipment, Double>
表示的原因。
因此,通常,您只需要首先弄清楚方法引用代表哪种方法,然后找到一个代表该方法的功能接口。有时,您需要自己创建一个功能接口!