2017-02-16 63 views
-1

以下几行中,为什么第一个和最后一个允许?什么时候知道我是否可以用lambda使用双冒号?

List<String> l = new ArrayList<>(); 

l.stream().forEach(System.out::println);//compiles 
l.stream().forEach(System.out.println(String::compareTo));//doesnt compile 
l.stream().forEach(String::compareTo);// doesnt compile 

String comparedWith = ""; 

l.stream().forEach(comparedWith::compareTo);//compiles why ? 

编辑

如果compareTo需要一个的说法,应该不是也工作?

如果根据文档:

表示接受单个输入参数,并将 返回任何结果的操作。与大多数其他功能界面不同的是,期望{}代码 Consumer}通过副作用进行操作。

回答

2

l.stream()的forEach(的System.out ::的println); //编译

这要求的System.out每个项目的println方法。这里System.out::println(String x) -> System.out.println(x)相同。

l.stream()的forEach(的System.out.println(字符串::的compareTo)); //犯规编译

你知道函数是如何调用的工作,对不对?首先拨打(System.out.println(String::compareTo),然后拨打l.stream().forEach(result of that println call)。除了println返回void,所以它没有结果。 。

l.stream()的forEach(字符串::的compareTo); //犯规编译

这里String::compareTo相同(String x, String y) -> x.compareTo(y)采用两个参数。但是forEach需要一个带一个参数的lambda表达式。

String comparingWith =“”;

l.stream()。forEach(comparisonWith :: compareTo); //编译原因?

这里comparedWith::compareTo(String x) -> comparedWith.compareTo(x)相同。这需要一个参数,所以它是有效的。

+0

为什么第三个例子和'(String x,String y) - > x.compareTo(y)'是一样的,你能否详细说明一下? –

+1

@estebanrincon,因为'''方法'compareTo'不是静态的,因此需要调用一个字符串;它也需要另一个字符串作为参数。 – immibis

+0

啊,理解,谢谢! –

1

forEach将采集集合中的每个元素并将其传递给您的函数。所以,你的函数只需要一个参数。

在你的情况下,println需要一个参数,因此它适合于forEach接受的操作。当你使用String(comparison)实例并调用compareTo时,它接受一个参数,并将当前字符串(在你的情况下为空字符串)与你的参数进行比较。 String中没有静态方法被称为compareTo,所以String :: compareTo不起作用。 。

+0

'compareTo'也需要一个参数,为什么它不起作用? –

+0

'comapareTo'实际上有两个参数,'this this引用调用实例,以及声明的参数:'x.compareTo(y)'。如上所述,相应的lambda是'(x,y) - > x.compareTo(y)'。流'forEach'只能找出'x'或'y'中的一个,所以它不会被编译。 –

1

双冒号或更准确地称为“方法引用”是为了选择一个将被调用的方法。

当调用方法时,匹配提供参数和预期参数的数量非常重要。

而且你可以很容易地推断,这些计数没有匹配你的第二个例子。

相关问题