I know it may be a very basic question on SO but I want to know what is the difference between a Predicate
and a Function
Interface in Java8?
Predicate<String> predicateTest = (s)-> s.length() > 5;
System.out.println(predicateTest.test("Predicate"));
Function<String, Boolean> functionTest = str -> str.length()> 5;
System.out.println(functionTest.apply("Function"));
Here in my Example both are returning true
.The only thing is way of calling is different ?
Difference between Predicate<T>
and Function<T, R>
First and foremost a Predicate<T>
is strictly a boolean-valued function:
_ _ _ _ _ _ _
| |
T --> | predicate | --> boolean
|_ _ _ _ _ _ _|
Whereas this is not necessarily true for a Function<T, R>
:
_ _ _ _ _ _ _
| |
T --> | function | --> R
|_ _ _ _ _ _ _|
The latter consumes any type of object just as Predicate<T>
enables but can vary in the return type.
Use case of Predicate<T>
and Function<T, R>
The use case for Predicate<T>
is when you require a function that consumes one argument of type T
and returns a boolean. e.g. that may be in a situation where you want to filter a stream of elements, find the first element from a stream that satisfies a condition as such of .filter(predicate).findFirst()
, or checking the presence of an element from a stream that satisfies a certain condition as such of anyMatch
, noneMatch
, allMatch
etc.
The use case for Function<T, R>
is when you require a function that consumes one argument of type T
and transforms that into a type R
e.g. that may be when calling stream.map(func)
.
Explanation of your code snippet:
In regards to the example snippet in your post Predicate<String>
and Function<String, Boolean>
are the same thing in terms of what they represent i.e. they both represent a function taking a String
and returning a boolean
. However, the former avoids boxing the returned value from boolean
to Boolean
whereas the latter does not.
That said, this does not necessarily mean wherever you can use a Predicate<String>
you can also use a Function<String, Boolean>
or vice versa.
Example:
While this compiles:
Predicate<String> predicate = p -> p.length() == 21;
Stream<String> stream = stringList().stream().filter(predicate);
This does not:
Function<String, Boolean> function = p -> p.length() == 21;
Stream<String> stream = stringList().stream().filter(function);
and vice versa:
While this works:
Function<String, Boolean> function = p -> p.length() == 21;
Stream<Boolean> stream = stringList().stream().map(function);
This does not:
Predicate<String> predicate = p -> p.length() == 21;
Stream<Boolean> stream = stringList().stream().map(predicate);