Поток AnyMatch принимает ссылку на метод, а не реализует предикат

Stream.anyMatch определяется как:

boolean anyMatch(Predicate<? super T> predicate)

Я создал новый класс следующим образом:

class ClassA  {    
    public boolean anyMethodName(Object o) {
        return o instanceof Integer;
    }
}

Тогда я могу запустить следующее:

List<String> durunitList = Arrays.asList("h", "d", "w", "m", "y");
ClassA classA = new ClassA();
System.out.println(durunitList.stream().peek(System.out::println).anyMatch(classA::anyMethodName));

Но в моем ClassA я не реализовал Predicate или его функциональный метод:

boolean test(T t)

Почему classA::anyMethodName все еще можно передать Stream.anyMatch(...)?

Как вы пришли к выражению classA::anyMethodName, единственная цель которого — сделать возможным то, чему вы сейчас удивляетесь? Почему вас удивляет возможность использования ссылки на метод там, где ожидается предикат, при этом замалчивая тот факт, что вы также используете System.out::println там, где ожидается Consumer?

Holger 29.07.2024 16:38
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
1
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В Java 8 добавлена ​​возможность интерфейсов быть «функциональными интерфейсами», если интерфейс имеет один абстрактный метод. Если да, то компилятор позволяет вам использовать метод (как лямбда-выражение или ссылку на метод classA::anyMethodName), как если бы он был экземпляром этого интерфейса, создавая для вас анонимный класс (при условии, что он имеет тот же тип возвращаемого значения). /параметры).

Предикат — это функциональный интерфейс, который позволяет вам напрямую использовать метод classA::anyMethodName, как если бы он был экземпляром Predicate.

В конце концов, ваш код фактически преобразуется в:

List<String> durunitList = Arrays.asList("h", "d", "w", "m", "y");
ClassA classA = new ClassA();
System.out.println(durunitList.stream().peek(System.out::println).anyMatch(new Predicate<String>() {
    @Override
    public boolean test(String o) {
        return classA.anyMethodName(o);
    }    
}));

ClassA никогда не приводится к Predicate (поскольку это не предикат...), но новый анонимный класс, который реализует Predicate, просто вызывает classA.anyMethodName за кулисами.

Но в моем определении ClassA НЕТ ключевого слова «реализует предикат», почему компилятор по-прежнему считает, что ClassA является реализацией предиката интерфейса?

user1169587 26.07.2024 18:51
ClassA никогда не рассматривается как Predicate и не приравнивается к нему. Обратите внимание, как в финальном коде (примера) создается новый анонимный класс, который реализует Predicate (следовательно, @Override public boolean test), который затем вызывает ваш метод classA.anyMethodName.
ipodtouch0218 26.07.2024 18:52

ваше второе предложение вводит в заблуждение, @FunctionalInterface АННОТАЦИЯ для этого не требуется - аннотация, как указано в предоставленной вами ссылке, является «информационной аннотацией» (аналогично @Override, не требуется, но проверяется, если присутствует) - Спецификация языка Java 9.8. Функциональные интерфейсы : «Функциональный интерфейс — это интерфейс, который не объявлен запечатанным и имеет только один абстрактный метод (кроме методов Object) и, таким образом, представляет собой единый функциональный контракт».

user85421 26.07.2024 19:19

@ user85421, спасибо, я перепишу эту часть! (также я называл их атрибутами, потому что у меня в голове был C#, лол)

ipodtouch0218 26.07.2024 19:51

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