Existe uma maneira de compor uma referência de método que é o oposto de uma referência de método atual. Veja a resposta da @ vlasec abaixo, que mostra como Predicate
converter explicitamente a referência de método para a e depois convertê-la usando a negate
função Essa é uma maneira dentre algumas outras maneiras não muito problemáticas de fazê-lo.
O oposto disso:
Stream<String> s = ...;
int emptyStrings = s.filter(String::isEmpty).count();
é isto:
Stream<String> s = ...;
int notEmptyStrings = s.filter(((Predicate<String>) String::isEmpty).negate()).count()
ou isto:
Stream<String> s = ...;
int notEmptyStrings = s.filter( it -> !it.isEmpty() ).count();
Pessoalmente, prefiro a técnica posterior porque acho mais claro ler do it -> !it.isEmpty()
que um elenco explícito longo e explícito e depois nego.
Também se poderia fazer um predicado e reutilizá-lo:
Predicate<String> notEmpty = (String it) -> !it.isEmpty();
Stream<String> s = ...;
int notEmptyStrings = s.filter(notEmpty).count();
Ou, se tiver uma coleção ou matriz, use um loop for que seja simples, tenha menos sobrecarga e * possa ser ** mais rápido:
int notEmpty = 0;
for(String s : list) if(!s.isEmpty()) notEmpty++;
* Se você quiser saber o que é mais rápido, use JMH http://openjdk.java.net/projects/code-tools/jmh e evite o código de referência manual, a menos que evite todas as otimizações da JVM - consulte Java 8: desempenho do Streams vs Colecções
** Estou recebendo críticas por sugerir que a técnica de loop for é mais rápida. Elimina a criação de um fluxo, elimina o uso de outra chamada de método (função negativa para predicado) e elimina uma lista / contador de acumuladores temporários. Portanto, algumas coisas que são salvas pela última construção que podem torná-la mais rápida.
Eu acho que é mais simples e agradável, mesmo que não seja mais rápido. Se o trabalho exigir um martelo e um prego, não traga uma serra elétrica e cola! Eu sei que alguns de vocês têm problemas com isso.
lista de desejos: Gostaria de ver as Stream
funções Java evoluírem um pouco agora que os usuários Java estão mais familiarizados com elas. Por exemplo, o método 'count' no Stream pode aceitar um Predicate
para que isso possa ser feito diretamente assim:
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 . Mas como esse problema ainda está aberto, veremos isso o mais cedo possível no Java 12 (se houver).