In mathematics, a predicate is commonly understood to be a boolean-valued function 'P: X? {true, false}' , called the predicate on X. Informally, a strong. It can be thought of as an operator or function that returns a value that is either true or false .

Java 8 Predicates Usage

In Java 8, Predicate is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference. So, where you think, we can use these true/false returning functions in day to day programming? I will say you can use predicates anywhere where you need to evaluate a condition on group/collection of similar objects such that evaluation can result either in true or false.

For example, you can use prdicates in these realtime usecases

Find all children borned after a particular date Pizzas ordered a specific time Employees greater than certain age and so on..

Java Predicate Class

So java predicates seems to be interesting thing. Let’s go deeper.

As I said, Predicate is functional interface. It mean we can pass lambda expressions wherever predicate is expected. For example one such method is filter() method from Stream interface.

/** * Returns a stream consisting of the elements of this stream that match * the given predicate. * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. * * @param predicate a non-interfering stateless predicate to apply to each element to determine if it * should be included in the new returned stream. * @return the new stream */ Stream<T> filter(Predicate<? super T> predicate);

We can assume a stream as a mechanism to create a sequence of elements supporting sequential and parallel aggregate operations. It means we can anytime collect and perform some operation of all elements present in the stream in one call.

So, essentially we can use stream and predicate to –

first filter certain elements from a group, and

then perform some operation on filtered elements.

Using Predicate on a collection

To demonstrate, we have an Employee class as below:

package predicateExample; public class Employee { public Employee(Integer id, Integer age, String gender, String fName, String lName){ this.id = id; this.age = age; this.gender = gender; this.firstName = fName; this.lastName = lName; } private Integer id; private Integer age; private String gender; private String firstName; private String lastName; //Please generate Getter and Setters //To change body of generated methods, choose Tools | Templates. @Override public String toString() { return this.id.toString()+" - "+this.age.toString(); } }

1. All Employees who are male and age more than 21

public static Predicate<Employee> isAdultMale() { return p -> p.getAge() > 21 && p.getGender().equalsIgnoreCase("M"); }

2. All Employees who are female and age more than 18

public static Predicate<Employee> isAdultFemale() { return p -> p.getAge() > 18 && p.getGender().equalsIgnoreCase("F"); }

3. All Employees whose age is more than a given age

public static Predicate<Employee> isAgeMoreThan(Integer age) { return p -> p.getAge() > age; }

You can build more of them as an when needed. So far so good. Far using above methods I have included above 3 methods in EmployeePredicates.java :

package predicateExample; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; public class EmployeePredicates { public static Predicate<Employee> isAdultMale() { return p -> p.getAge() > 21 && p.getGender().equalsIgnoreCase("M"); } public static Predicate<Employee> isAdultFemale() { return p -> p.getAge() > 18 && p.getGender().equalsIgnoreCase("F"); } public static Predicate<Employee> isAgeMoreThan(Integer age) { return p -> p.getAge() > age; } public static List<Employee> filterEmployees (List<Employee> employees, Predicate<Employee> predicate) { return employees.stream() .filter( predicate ) .collect(Collectors.<Employee>toList()); } }

You see I have created another utility method filterEmployees() to show java predicate filter. It is basically to make code clean and less repetitive. You can also write more than one predicates to make predicate chain, as we do in builder pattern.

So, in this function we pass the list of employees and we pass a predicate, then this function will return a new collection of employees satisfying the condition mentioned in parameter predicate.

package predicateExample; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import static predicateExample.EmployeePredicates.*; public class TestEmployeePredicates { public static void main(String[] args) { Employee e1 = new Employee(1,23,"M","Rick","Beethovan"); Employee e2 = new Employee(2,13,"F","Martina","Hengis"); Employee e3 = new Employee(3,43,"M","Ricky","Martin"); Employee e4 = new Employee(4,26,"M","Jon","Lowman"); Employee e5 = new Employee(5,19,"F","Cristine","Maria"); Employee e6 = new Employee(6,15,"M","David","Feezor"); Employee e7 = new Employee(7,68,"F","Melissa","Roy"); Employee e8 = new Employee(8,79,"M","Alex","Gussin"); Employee e9 = new Employee(9,15,"F","Neetu","Singh"); Employee e10 = new Employee(10,45,"M","Naveen","Jain"); List<Employee> employees = new ArrayList<Employee>(); employees.addAll(Arrays.asList(new Employee[]{e1,e2,e3,e4,e5,e6,e7,e8,e9,e10})); System.out.println( filterEmployees(employees, isAdultMale()) ); System.out.println( filterEmployees(employees, isAdultFemale()) ); System.out.println( filterEmployees(employees, isAgeMoreThan(35)) ); //Employees other than above collection of "isAgeMoreThan(35)" //can be get using negate() System.out.println(filterEmployees(employees, isAgeMoreThan(35).negate())); } } Output: [1 - 23, 3 - 43, 4 - 26, 8 - 79, 10 - 45] [5 - 19, 7 - 68] [3 - 43, 7 - 68, 8 - 79, 10 - 45] [1 - 23, 2 - 13, 4 - 26, 5 - 19, 6 - 15, 9 - 15]

Predicates are really very good addition in Java 8 and I am going to use it whenever I will get chance.

Final Thoughts on Predicates in Java 8

They move your conditions (sometimes business logic) to a central place. This helps in unit-testing them separately. Any change need not be duplicated into multiple places. Java predicate improves code maintenance. The code e.g. “filterEmployees(employees, isAdultFemale())” is very much readable than writing a if-else block.

Well, those are my thoughts in Java 8 predicates. What do you think of this feature? Share with all of us in the comments section.

Happy Learning !!

Read More :

Java Predicate Negate Example

Java chained predicates – logical AND and logical OR operations