功能接口作为功能参考

Function interface as function reference

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 采用函数引用,只有那些采用一个参数且 returns 一个参数的方法可以映射到此。但是在上面的代码中,getValue 被映射并且工作正常,但它不接受任何参数。代码应该给出构建问题但没有。我的概念有问题吗?

单参数comparing方法:

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor)

接受一个 Function<? super T, ? extends U> 参数,这是一个功能接口,包含一个方法,该方法接受一种类型的参数,returns 是另一种类型的值。

Entry::getValue 采用一种类型的参数(在您的示例中为 Map.Entry<String, Integer>),并且 return 为其他类型的值(在您的示例中为 Integer)。因此它匹配 Function 功能接口。

But in above code getValue is mapped and works fine but it doesn't take any parameter.

是的 - 来自 Stream 的每个 Map.Entry 元素用作 Function 接口的 apply() 方法的参数。

也许这会澄清:

Function<Map.Entry<Integer, String>, String> func = Map.Entry::getValue;

Map.EntrygetValue() 方法可以被视为接受 Map.Entry 实例的 Function 和 return 该实例的值(return 通过在该实例上调用 getValue() 来编辑)。

在这种情况下,您的方法引用是实例方法,而不是静态方法,因此不是为每个项目调用和使用以下值:

Entry.getValue(item)

它使用

item.getValue() [Java文档] (https://docs.oracle.com/javase/7/docs/api/java/util/Map.Entry.html#getValue())

所以它充当 lambda:p -> p.getValue(),将一个条目转换为它的值以进行比较,因为它有一个参数和 returns 一个值而不抛出异常它可以实现 Function<Entry<String, Integer>, Integer>.

如果同时存在静态方法和实例方法,则不能使用方法引用,按照这个问题:Link

Worked example