注意:这个问题来自于先前的SO问题的无效链接,但是这里...
请参阅以下代码(注意:我确实知道此代码将无法“工作”,并且应使用Integer::compare
-我只是从链接的问题中提取了它):
final ArrayList <Integer> list
= IntStream.rangeClosed(1, 20).boxed().collect(Collectors.toList());
System.out.println(list.stream().max(Integer::max).get());
System.out.println(list.stream().min(Integer::min).get());
根据
.min()
和 .max()
的javadoc,两者的参数都应为Comparator
。但是这里的方法引用是 Integer
类的静态方法。那么,为什么要编译呢?
最佳答案
让我解释一下这里发生的事情,因为这并不明显!
首先, Stream.max()
接受 Comparator
的一个实例,以便可以将流中的项目相互比较以找到最大值或最小值,而您无需担心太多,就可以找到最佳顺序。
因此,问题是,为什么 Integer::max
被接受?毕竟它不是比较器!
答案是,新的lambda功能可以在Java 8中工作。它依赖于一个被非正式地称为“单一抽象方法”接口(interface)或“SAM”接口(interface)的概念。这个想法是,具有一个抽象方法的任何接口(interface)都可以由任何lambda(或方法引用)自动实现,这些方法的方法签名与该接口(interface)上的一个方法匹配。因此,检查 Comparator
接口(interface)(简单版本):
public Comparator<T> {
T compare(T o1, T o2);
}
如果一个方法正在寻找
Comparator<Integer>
,那么它实质上是在寻找这个签名:int xxx(Integer o1, Integer o2);
我使用“xxx” ,因为方法名称未用于匹配目的。
因此,
Integer.min(int a, int b)
和Integer.max(int a, int b)
都足够接近,自动装箱将使它在方法上下文中显示为Comparator<Integer>
。