Функциональный интерфейс как справочник функций

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>,

Если существует как статический метод, так и метод экземпляра, вы не можете использовать ссылку на метод согласно этому вопросу: Ссылка

Работал пример

Другие вопросы по тегам