public static void main(String o[]) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
map.entrySet().stream().sorted(Comparator.comparing(Entry::getValue)).forEach(System.out::println);
}
上面的代码构建和运行完美,但它不应该。 Comparator.comparing采用函数引用,只有那些接受一个参数并返回一个参数的方法才能映射到此。但是在上面的代码中,getValue被映射并且工作正常,但它没有采用任何参数。代码应该给出构建问题,但不是。我的概念有什么问题吗?
答案 0 :(得分:5)
单个参数comparing
方法:
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor)
采用Function<? super T, ? extends U>
参数,这是一个函数接口,它包含一个方法,该方法接受一种类型的参数并返回其他类型的值。
Entry::getValue
接受一种类型的参数(在您的示例中为Map.Entry<String, Integer>
)并返回其他类型的值(示例中为Integer
)。因此它匹配Function
功能接口。
但是在上面的代码中,getValue被映射并且工作正常,但它没有采用任何参数。
是的 - 从Map.Entry
获取的每个Stream
元素都充当apply()
接口的Function
方法的参数。
也许这会澄清:
Function<Map.Entry<Integer, String>, String> func = Map.Entry::getValue;
getValue()
Map.Entry
方法可被视为Function
接受Map.Entry
实例并返回该实例的值(通过调用{{1}返回)在那个实例上)。
答案 1 :(得分:2)
在这种情况下,您的方法引用是一个实例方法,而不是静态方法,因此不是为每个项调用并使用以下值:
getValue()
使用
Entry.getValue(item)
[JavaDoc的]
(https://docs.oracle.com/javase/7/docs/api/java/util/Map.Entry.html#getValue())
所以它充当lambda:item.getValue()
,将一个条目转换为它的值进行比较,因为它有一个参数并返回一个值而不抛出它可以实现的异常p -> p.getValue()
。
如果静态和实例方法都存在,则无法使用方法引用,如此问题:Link