Hay una manera de componer una referencia de método que es lo contrario de una referencia de método actual. Vea la respuesta de @ vlasec a continuación que muestra cómo al Predicateconvertir explícitamente la referencia del método a a y luego convertirla utilizando la negatefunción. Esa es una forma entre algunas otras formas no demasiado problemáticas de hacerlo.
Lo contrario de esto:
Stream<String> s = ...;
int emptyStrings = s.filter(String::isEmpty).count();
Es esto:
Stream<String> s = ...;
int notEmptyStrings = s.filter(((Predicate<String>) String::isEmpty).negate()).count()
o esto:
Stream<String> s = ...;
int notEmptyStrings = s.filter( it -> !it.isEmpty() ).count();
Personalmente, prefiero la técnica posterior porque me resulta más claro de leer it -> !it.isEmpty()que un reparto explícito largo y detallado y luego negarlo.
También se podría hacer un predicado y reutilizarlo:
Predicate<String> notEmpty = (String it) -> !it.isEmpty();
Stream<String> s = ...;
int notEmptyStrings = s.filter(notEmpty).count();
O, si tiene una colección o matriz, simplemente use un bucle for que sea simple, tenga menos sobrecarga y * podría ser ** más rápido:
int notEmpty = 0;
for(String s : list) if(!s.isEmpty()) notEmpty++;
* Si desea saber qué es más rápido, utilice JMH http://openjdk.java.net/projects/code-tools/jmh y evite el código de referencia manual a menos que evite todas las optimizaciones de JVM; consulte Java 8: rendimiento de Streams vs Colecciones
** Estoy recibiendo críticas por sugerir que la técnica for-loop es más rápida. Elimina la creación de una secuencia, elimina el uso de otro método de llamada (función negativa para predicado) y elimina una lista / contador de acumulador temporal. Entonces, algunas cosas que se guardan en la última construcción pueden hacerlo más rápido.
Sin embargo, creo que es más simple y agradable, incluso si no es más rápido. Si el trabajo requiere un martillo y un clavo, ¡no traiga una motosierra y pegamento! Sé que algunos de ustedes están en desacuerdo con eso.
lista de deseos: Me gustaría ver que las Streamfunciones de Java evolucionen un poco ahora que los usuarios de Java están más familiarizados con ellas. Por ejemplo, el método 'contar' en Stream podría aceptar a Predicatepara que esto se pueda hacer directamente así:
Stream<String> s = ...;
int notEmptyStrings = s.count(it -> !it.isEmpty());
or
List<String> list = ...;
int notEmptyStrings = lists.count(it -> !it.isEmpty());
Predicate.not(Predicate)método estático . Pero ese problema aún está abierto, así que lo veremos lo antes posible en Java 12 (si es que lo ha hecho).