So assuming I use some random filter on a stream, the most straightforward way is to directly input the Predicate:
x.stream().filter(e -> e % 2 == 0)
As well I can simply make a reference and define the Predicate in advance:
Predicate<Integer> isEven = e -> e % 2 == 0;
...
x.stream().filter(isEven)
But I can as well use a function:
private static boolean isEven(Integer integer) {
return integer % 2 == 0;
}
...
x.stream().filter(MyClass::isEven)
As far as I can tell, the Predicate is of course much more limited while the function might have side effects etc. But since people like Venkat Subramaniam use the latter solution, I really wonder: What are the main differences here?
Function interface is used to do the transformation.It can accepts one argument and produces a result. On the other side, Predicate can also accept only one argument but it can only return boolean value. It is used to test the condition.
A Predicate is just a function that takes an object of some type and returns a boolean. A Function is a generalization which can return any type, not just Boolean 's.
Java stream provides a method filter() to filter stream elements on the basis of given predicate. Suppose you want to get only even elements of your list then you can do this easily with the help of filter method. This method takes predicate as an argument and returns a stream of consisting of resulted elements.
Java Predicate Interface It is a functional interface which represents a predicate (boolean-valued function) of one argument. It is defined in the java. util. function package and contains test() a functional method.
No! Predicate is not really limited in comparison to a method reference! In fact, these things are all the same!
Just look at the filter()
function signature:
filter(Predicate<? super T> predicate)
And let's consider your examples:
x.stream().filter(e -> e % 2 == 0)
Predicate<Integer> isEven = e -> e % 2 == 0;
...
x.stream().filter(isEven)
The first one is just an inlined version of the latter.
private static boolean isEven(Integer integer) {
return integer % 2 == 0;
}
...
x.stream().filter(MyClass::isEven)
and here you can see Method References
in action. MR are just a syntactic sugar allowing you to define Lambda Expression based on already existing functions.
At the end of the day all those expressions become the same implementation of Predicate functional interface.
Also, you can also perform side effects in your Lambda Expressions by using block syntax on the right side but it's generally not advised:
e -> {
//side effects here
return e % 2 == 0;
}
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