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 .