Java 8 Predicates and Functions
Introduction
Google Guava library users are already familiar with the concepts that we will cover in this article. Predicate and Function are a couple of useful Functional Interfaces introduced in Java 8 (more information about Functional Interfaces in the following article: Java 8 Lambda expressions example).
Let us see which features each one of these interfaces provide.
Predicate
Predicates represent single argument functions that return a boolean value:
Predicate<Integer> greaterThanTen = (i) -> i > 10; // Will print true greaterThanTen.test(14);
Predicates may also be chained together by the means of and, or and negate. Following next is a simple example but one may write complex evaluation rules by chaining predicates:
Predicate<Integer> greaterThanTen = (i) -> i > 10; Predicate<Integer> lowerThanTwenty = (i) -> i < 20; // Will print true greaterThanTen.and(lowerThanTwenty).test(15); // Will print false greaterThanTen.and(lowerThanTwenty).negate().test(15)
Predicates may also be passed into functions:
// Will print "Number 10 was accepted!"
process(10, (i) -> i > 7);
void process(int number, Predicate<Integer> predicate) {
if (predicate.test(number)) {
System.out.println("Number " + number + " was accepted!");
}
}
Another example:
List<User> users = new ArrayList<>();
users.add(new User("John", "admin"));
users.add(new User("Peter", "member"));
List<User> admins = process(users, (u) -> u.getRole().equals("admin"));
List<User> process(List<User> users, Predicate<User> predicate) {
List<User> result = new ArrayList<>();
for (User user : users) {
if (predicate.test(user)) {
result.add(user);
}
}
return result;
}
Function
Functions also represent a single argument function but they return a result of an arbitrary type:
Function<String, Integer> stringLength = (s) -> s.length();
// Will print 11
stringLength.apply("Hello world");
Functions may also be chained:
Function<String, Integer> stringLength = (s) -> s.length();
Function<Integer, Boolean> greaterThanFive = (i) -> i > 5;
// Will print true
stringLength.andThen(greaterThanFive).apply("Hello world");
Another function chaining example:
Function<String, Integer> stringLength = (s) -> s.length();
Function<Integer, Boolean> lowerThanTen = (i) -> i < 10;
Function<String, Boolean> function = stringLength.andThen(lowerThanTen);
// Will print false
function.apply("Hello world");