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 Predicate
convertir explícitamente la referencia del método a a y luego convertirla utilizando la negate
funció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 Stream
funciones 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 Predicate
para 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).