33

Lets say I have a Stream of Strings.

final Stream<String> stream = ...;

I want to filter out each empty string after trimmed.

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

Is there any way to apply Predicate#negate() for replacing v -> !v.isEmpty() part?

.filter(((Predicate) String::isEmpty).negate()) // not compile
Misha
  • 27,433
  • 6
  • 62
  • 78
Jin Kwon
  • 20,295
  • 14
  • 115
  • 184

4 Answers4

32

You would have to do .filter(((Predicate<String>) String::isEmpty).negate())

If you want, you can define

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

and then

.filter(not(String::isEmpty))

but I would just stick with v -> !v.isEmpty()

Misha
  • 27,433
  • 6
  • 62
  • 78
8

It seems like you have to cast to Predicate<String> for this to work:

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

Of course, it would be much shorter to use a lambda in this case:

.filter(s -> ! s.isEmpty())
tobias_k
  • 81,265
  • 12
  • 120
  • 179
3

Instead of creating classes by yourself use durian utility library. It has a lot of methods: and, or and not of course:

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

stream
.filter(Objects::nonNull)
.map(String::trim)
.filter(not(String::isEmpty));
Cherry
  • 31,309
  • 66
  • 224
  • 364
2

Starting from java 11 you can use Predicate#not

import static java.util.function.Predicate.not;

stream
.filter(Objects::nonNull)
.map(String::trim)
.filter(not(String::isEmpty));
Pieter De Bie
  • 1,074
  • 13
  • 30