Статьи

Java 8 Streams: фильтрация и отрицание предикатов

Недавно состоялось интересное обсуждение использования отрицания предикатов в методе .filter в потоке членами списка рассылки LJC , поэтому я подумал, что стоило бы кратко изложить это в сообщении в блоге. Обсуждение было о том, как использовать .filter и отрицать предикат.

Это, возможно, то, как вы могли бы думать о выполнении, но вот несколько альтернативных способов

1
2
Stream.of(1, 2, 3, 4, 5, 6, 7)
      .filter(((Predicate) c -> c % 2 == 0).negate())

Ответ 1: написать метод предиката

Вы можете упростить это, написав служебный метод, который выполняет отрицание.

1
2
3
public static <R> Predicate<R> not(Predicate<R> predicate) {
      return predicate.negate();
}

Что приводит к гораздо более аккуратному коду.

1
2
Stream.of(1, 2, 3, 4, 5, 6, 7)
      .filter(not(c -> c % 2 == 0))

Ответ 2. Используйте функцию идентификации для преобразования ссылки на метод в предикат

Мы используем служебный метод для преобразования ссылки на метод в предикат.

1
2
3
public static <T> Predicate<T> predicate(Predicate<T> predicate) {
      return predicate;
}

хотя код не такой аккуратный.

1
2
Stream.of("Cat", "", "Dog")
      .filter(predicate(String::isEmpty).negate())

Ответ 3: используйте оператор not (!)

Используйте знакомый не оператор.

1
2
3
4
5
Stream.of(1, 2, 3, 4, 5, 6, 7)
      .filter((c -> c % 2 != 0))
 
Stream.of("Cat", "", "Dog")
      .filter(str -> !str.isEmpty())

Код намного проще и сразу знаком.

Утверждается, что ссылки на методы часто сложнее читать и сложнее при рефакторинге, чем простые лямбды, и что смешение лямбд и ссылок на методы в цепочке потоков вводит читателя в заблуждение. Ссылка: Java SE 8 Best Practices

Когда вы используете ссылку на метод и хотите, чтобы среда IDE создала метод, IntelliJ создает его как статический метод с объектом в качестве первого аргумента. Использование оператора not позволяет избежать этого.

Вот несколько полезных ссылок:

Ссылка: Java 8 Streams: отфильтруйте и отрицайте отрицание от нашего партнера по JCG Алекса Тидома из блога alex.theedom .