«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.