Java 8 - Filtering with predicates

We will start with What Predicate is and then write example on how to filter data with predicates and also discuss about predicate chaining.

Previous posts

1. What is java.util.function Predicate?

Predicate is like a condition checker, which accepts one argument of type T and return the boolean value.

It's a functional interface with functional method test(T). Here, Object is typed.

@FunctionalInterface
interface Predicate<T> {
public boolean test(T t);
}

2. How to filter data with Predicate?

Consider we have Collection of employees and we want to filter them based on age, sex, salary and/ or with any other combinations. We can do that with Predicate. Let's understand it with a short example.

class Employee {
private long id;
private String firstName;
private String lastName;
private int age;
private Sex sex;
private int salary;

// getters, constructor, hashCode, equals, to String
}

Defining predicates for filtering

Predicate<Employee> male = e -> e.getSex() == Sex.MALE;
Predicate<Employee> female = e -> e.getSex() == Sex.FEMALE;
Predicate<Employee> ageLessThan30 = e -> e.getAge() < 30;
Predicate<Employee> salaryLessThan20 = e -> e.getSalary() < 20000;
Predicate<Employee> salaryGreaterThan25 = e -> e.getSalary() > 25000;

Filtering employees with Predicates

employees.stream().filter(male).collect(Collectors.toList());
employees.stream().filter(female).collect(Collectors.toList());
employees.stream().filter(ageLessThan30).collect(Collectors.toList());
employees.stream().filter(salaryLessThan20).collect(Collectors.toList());

Here, employees reference is of type java.util.List.

Collections framework is retrofitted for Streaming API and have stream() and parallelStream() methods along with few other additions like filter() method is defined in Stream. We are streaming employees collection and filtering them based on the Predicate and then collecting as java.util.List.

3. Predicate chaining

java.util.function.Predicate have three default method. Two of them and(Predicate<T> other) and or(Predicate<T> other) is used for predicate chaining.

3.1. Filtering employees with multiple predicates

Let's say, we want to filter collection of employees which involves multiple conditions like

Let's understand it with an example code.

Defining predicates
// Point 1
Predicate<Employee> male = e -> e.getSex() == Sex.MALE;
// Point 2
Predicate<Employee> female = e -> e.getSex() == Sex.FEMALE;
// Point 3
Predicate<Employee> ageLessThan30 = e -> e.getAge() < 30;
// Point 4
Predicate<Employee> salaryLessThan20 = e -> e.getSalary() < 20000;
// Point 5
Predicate<Employee> salaryGreaterThan25 = e -> e.getSalary() > 25000;
// Point 6
Predicate<Employee> salaryLessThan20OrGreateThan25 = salaryLessThan20.or(salaryGreaterThan25);
// Point 7
Predicate<Employee> allMaleSalaryLessThan20 = male.and(salaryLessThan20);
// Point 8
Predicate<Employee> allMaleAgeLessThan30 = male.and(ageLessThan30);
// Point 9
Predicate<Employee> allFemaleSalaryGreaterThan25 = female.and(salaryGreaterThan25);
// Point 10
Predicate<Employee> allMaleSalaryLessThan20OrGreateThan25 = male.and(salaryLessThan20OrGreateThan25);
Filtering employees with predicate chaining
employees.stream().filter(allMaleSalaryLessThan20).collect(Collectors.toList());
employees.stream().filter(allMaleAgeLessThan30).collect(Collectors.toList());
employees.stream().filter(allFemaleSalaryGreaterThan25).collect(Collectors.toList());
employees.stream().filter(allMaleSalaryLessThan20OrGreateThan25).collect(Collectors.toList());

This is how we can use Predicate to filter in-memory data. I hope you find this post informative and helpful. You can get the full example code on Github.



Tags: java.util.function package, BiConsumer in Java 8, Consumer in Java 8, Function in Java 8, Predicate in Java 8, Supplier in Java 8, Java, Java 8

← Back home