web-dev-qa-db-fra.com

Comment annuler un prédicat lambda?

Disons que j'ai un flux de cordes.

final Stream<String> stream = ...;

Je veux filtrer chaque chaîne vide après avoir coupé.

stream
    .filter(Objects::nonNull)
    .map(String::trim)
    .filter(v -> !v.isEmpty());

Existe-t-il un moyen d'appliquer Predicate # negate () pour remplacer la partie v -> !v.isEmpty()?

.filter(((Predicate) String::isEmpty).negate()) // not compile
27
Jin Kwon

Vous devez faire .filter(((Predicate<String>) String::isEmpty).negate())

Si vous le souhaitez, vous pouvez définir

static<T> Predicate<T> not(Predicate<T> p) {
    return t -> !p.test(t);
}

puis

.filter(not(String::isEmpty))

mais je resterais avec v -> !v.isEmpty()

29
Misha

Il semble que vous devez lancer un casting sur Predicate<String> pour que cela fonctionne:

.filter(((Predicate<String>) (String::isEmpty)).negate())

Bien sûr, il serait beaucoup plus court d'utiliser un lambda dans ce cas:

.filter(s -> ! s.isEmpty())
7
tobias_k

Au lieu de créer des classes par vous-même, utilisez la bibliothèque d'utilitaires durian . Il a beaucoup de méthodes : and, or et not bien sûr:

import static com.diffplug.common.base.Predicates.not;

stream
.filter(Objects::nonNull)
.map(String::trim)
.filter(not(String::isEmpty));
2
Cherry