Функциональный интерфейс как справочник функций
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 отображается и работает нормально, но не принимает никаких параметров. Код должен дать проблему сборки, но не дает. Есть ли проблема с моей концепцией?
2 ответа
Единственный аргумент 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
экземпляр и возвращает значение этого экземпляра (возвращается путем вызова getValue()
в этом случае).
В этом случае ваша ссылка на метод является методом экземпляра, а не статическим, поэтому вместо каждого вызова элемента и использования значения:
Entry.getValue(item)
Оно использует
item.getValue()
[JavaDoc] ( https://docs.oracle.com/javase/7/docs/api/java/util/Map.Entry.html)
так действует как лямбда p -> p.getValue()
преобразование записи в ее значение для сравнения, так как она имеет один аргумент и возвращает одно значение, не выдавая исключений, которые она может реализовать Function<Entry<String, Integer>, Integer>
,
Если существует как статический метод, так и метод экземпляра, вы не можете использовать ссылку на метод согласно этому вопросу: Ссылка