I need to compose a stream operation with a predicate based on a boolean function. Found a workaround via rethrowing a method's 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 seems to do nothing, however not this:
public List<String> foo() {
return new ArrayList<String>().stream()
.filter((String::isEmpty).negate())
.collect(Collectors.toList());
}
nor any in-line conversion:
public List<String> foo() {
return new ArrayList<String>().stream()
.filter(((Predicate)String::isEmpty).negate())
.collect(Collectors.toList());
}
seems to work. Fails with the error
The target type of this expression must be a functional interface
What the fancy conversion happens in the 'pred(...)' method?
Retrieves rows where the value of an expression is true, false, or unknown (null).
Generally predicate means a statement that determines whether a value could be true or false. In programming predicates mean functions with one argument that return a boolean value.
Predicate functions are functions that return a single TRUE or FALSE . You use predicate functions to check if your input meets some condition. For example, is. character() is a predicate function that returns TRUE if its input is of type character and FALSE otherwise.
Functional Interface: This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference. Represents a predicate (boolean-valued function) of one argument. This is a functional interface whose functional method is test(Object) .
You could write a utility 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 it's more readable than casting to a Predicate<T>
:
.filter(((Predicate<String>)String::isEmpty).negate())
Though I would go with a simple lambda:
s -> !s.isEmpty()
What the fancy conversion happens in the
pred(...)
method?
You have specified a context - the type to work with. For instance, a String::isEmpty
could be a 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 the Predicate<T>
. The compiler is now able to figure out what the type you want to use.
You can use
((Predicate<String>) String::isEmpty).negate()
(note the use of the proper generic type)
or (preferred):
s -> !s.isEmpty()
which is way simpler and readable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With