Интересуют случаи где можно применить negate, and и or. Ну и к тому же не пойму в общем как они работают. Объясните пожалуйста.
Предположим у вас есть предикат, который единожды сохранён в переменную и используется во многих участках кода. Для простоты возьмём ссылку на метод isEmpty класса String, проверяющий строку на пустоту:
Predicate<String> isEmpty = String::isEmpty;
Но в одних участках кода надо использовать его для нахождения пустых строк, а в других наоборот непустых. Например, вы считали из файла строки и хотите отбросить пустые:
Files.lines(Paths.get(fileName))
.filter(isEmpty.negate())
...
Без метода negate вам пришлось бы использовать более многословную и менее идиоматичную конструкцию с дополнительной лямбдой:
Files.lines(Paths.get(fileName))
.filter(s -> !isEmpty.test(s))
...
Повторюсь, isEmpty используется только для примера. Тут мог бы быть какой-нибудь нестандартный и более сложный предикат.
Методы or и and позволяют объединять предикаты, благодаря чему можно, например, в одной операции filter выполнить цепочку проверок. Вот пример из моего другого ответа, динамический конструирующий предикат из набора заранее неизвестных условий:
Predicate<Entity> p = Arrays.stream(flags)
.map(f -> e -> (f & e.getFlags()) > 0)
.reduce(Predicate::or)
.orElse(t -> false);
data.stream()
.filter(p)
.collect(Collectors.toList());
Сборка персонального компьютера от Artline: умный выбор для современных пользователей