Predicate from function reference (Boolean type)

I need to create a stream operation with a predicate based on a boolean function. A workaround was found by reorganizing the method argument as a predicate, as shown:

public <T> Predicate<T> pred(final Predicate<T> aLambda) { return aLambda; } public List<String> foo() { return new ArrayList<String>().stream() //of course, this does nothing, simplified .filter(pred(String::isEmpty).negate()) .collect(Collectors.toList()); } 

The 'pred' method does not seem to do anything, but not this:

 public List<String> foo() { return new ArrayList<String>().stream() .filter((String::isEmpty).negate()) .collect(Collectors.toList()); } 

and no built-in conversion:

 public List<String> foo() { return new ArrayList<String>().stream() .filter(((Predicate)String::isEmpty).negate()) .collect(Collectors.toList()); } 

seems to work. Error with error

The target type of this expression must be a functional interface.

What bizarre conversion happens in the pred (...) method?

+7
java java-8 functional-interface predicate
source share
3 answers

You can write a useful method:

 class PredicateUtils { public static <T> Predicate<T> not(Predicate<T> predicate) { return predicate.negate(); } } 

and use it as follows:

 .filter(not(String::isEmpty)) 

I believe this is more readable than casting to Predicate<T> :

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

Although I would go with a simple lambda:

 s -> !s.isEmpty() 

What bizarre conversion happens in the pred(...) method?

You specified a context - type of work. For example, String::isEmpty could be Function<String, Boolean> , or Predicate<String> , or my @FunctionalInterface , or something else.

You clearly said that you were expecting a Predicate<T> , and you would return an instance of Predicate<T> . Now the compiler can determine which type you want to use.

+7
source share

you can use

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

(note the use of the correct generic type)

or (preferred):

 s -> !s.isEmpty() 

which is simpler and more readable.

+5
source share

Your third version almost worked:

 Arrays.<String>asList("Foo", "Bar", "").stream() .filter(((Predicate<String>)String::isEmpty).negate()) .collect(Collectors.toList()); 

It seems like compilation is just fine.

+2
source share

All Articles