Існує спосіб скласти посилання на метод, протилежний поточному посиланню на метод. Див. Відповідь @ 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 (якщо взагалі).