注意:这个问题来自于先前的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>

10-08 08:58
查看更多