Перейти к основному содержимому

Отменить ссылку на метод предиката с помощью Java 11

· 2 мин. чтения

1. Обзор

В этом кратком руководстве мы увидим, как отменить ссылку на метод Predicate с помощью Java 11.

Мы начнем с ограничений, с которыми столкнулись, чтобы достичь этого до Java 11. Затем мы увидим , как помогает метод Predicate.not() .

2. До Java 11

Во-первых, давайте посмотрим, как нам удалось отменить предикат до Java 11.

Для начала создадим класс Person с полем age и методом isAdult() :

public class Person {
private static final int ADULT_AGE = 18;

private int age;

public Person(int age) {
this.age = age;
}

public boolean isAdult() {
return age >= ADULT_AGE;
}
}

Теперь давайте представим, что у нас есть список людей:

List<Person> people = Arrays.asList(
new Person(1),
new Person(18),
new Person(2)
);

И мы хотим вернуть всех взрослых. Чтобы добиться этого в Java 8, мы можем:

people.stream()                      
.filter(Person::isAdult)
.collect(Collectors.toList());

Однако что, если вместо этого мы хотим получить невзрослых людей? Тогда мы должны отрицать предикат:

people.stream()                       
.filter(person -> !person.isAdult())
.collect(Collectors.toList());

К сожалению, мы вынуждены отказаться от ссылки на метод, хотя нам кажется, что ее легче читать. Возможный обходной путь — создать метод isNotAdult() в классе Person , а затем использовать ссылку на этот метод:

people.stream()                 
.filter(Person::isNotAdult)
.collect(Collectors.toList());

Но, может быть, мы не хотим добавлять этот метод в наш API, а может, просто не можем, потому что класс не наш. Именно тогда появляется Java 11 с методом Predicate.not() , как мы увидим в следующем разделе.

3. Метод Predicate.not ()

Статический метод Predicate.not() был добавлен в Java 11 для отмены существующего Predicate .

Давайте возьмем наш предыдущий пример и посмотрим, что это значит. Вместо использования лямбда-выражения или создания нового метода в классе Person мы можем просто использовать этот новый метод:

people.stream()                          
.filter(Predicate.not(Person::isAdult))
.collect(Collectors.toList());

Таким образом, нам не нужно изменять наш API, и мы по-прежнему можем полагаться на удобочитаемость ссылок на методы.

Мы можем сделать это еще яснее с помощью статического импорта:

people.stream()                  
.filter(not(Person::isAdult))
.collect(Collectors.toList());

4. Вывод

В этой короткой статье мы увидели, как использовать метод Predicate .not() , чтобы поддерживать использование ссылок на методы для предикатов, даже если они инвертированы.

Как обычно, полный код статьи можно найти на GitHub .