Існує спосіб скласти посилання на метод, протилежний поточному посиланню на метод. Див. Відповідь @ vlasec нижче, де показано, як явно передати посилання методу на a, Predicate
а потім перетворити його за допомогою negate
функції. Це один із способів зробити кілька інших не надто клопітких способів.
Протилежне цьому:
Stream<String> s = ...;
int emptyStrings = s.filter(String::isEmpty).count();
це є:
Stream<String> s = ...;
int notEmptyStrings = s.filter(((Predicate<String>) String::isEmpty).negate()).count()
або це:
Stream<String> s = ...;
int notEmptyStrings = s.filter( it -> !it.isEmpty() ).count();
Особисто я віддаю перевагу більш пізній техніці, тому що мені стає зрозуміліше читати, it -> !it.isEmpty()
ніж довгий багатослівний чіткий виступ, а потім заперечувати.
Можна також скласти присудок і повторно використовувати його:
Predicate<String> notEmpty = (String it) -> !it.isEmpty();
Stream<String> s = ...;
int notEmptyStrings = s.filter(notEmpty).count();
Або якщо у вас колекція чи масив, просто використовуйте цикл for, який простий, має менші накладні витрати, і * може бути ** швидше:
int notEmpty = 0;
for(String s : list) if(!s.isEmpty()) notEmpty++;
* Якщо ви хочете знати, що швидше, то використовуйте JMH http://openjdk.java.net/projects/code-tools/jmh і уникайте контрольного коду, якщо це не дозволяє уникнути всіх оптимізацій JVM - див. Java 8: продуктивність потоків проти колекцій
** Мені стає важко сказати, що техніка for-loop швидша. Це виключає створення потоку, виключає використання іншого виклику методу (негативна функція для предиката), а також усуває тимчасовий список акумуляторів / лічильник. Отже, кілька речей, які зберігаються останньою конструкцією, які можуть зробити це швидше.
Я думаю, що це простіше і приємніше, хоча навіть і не швидше. Якщо робота вимагає молотка та цвяха, не приносьте бензопилу та клей! Я знаю, що деякі з вас вирішують це.
список побажань: Я хотів би, щоб Stream
функції Java трохи розвивалися зараз, коли користувачі Java більше знайомі з ними. Наприклад, метод 'count' в потоці може прийняти Predicate
так, що це можна зробити безпосередньо так:
Stream<String> s = ...;
int notEmptyStrings = s.count(it -> !it.isEmpty());
or
List<String> list = ...;
int notEmptyStrings = lists.count(it -> !it.isEmpty());
Predicate.not(Predicate)
методу. Але це питання все ще залишається відкритим, тому ми побачимо це якнайшвидше на Java 12 (якщо взагалі).