Learn more about Java Predicate<T>

Soy Phea
3 min readJul 29, 2020

--

After I have been working with Java programming for longtime a go. I just start to realised that, I have to be immersing on Java functional programming which that we always call declarative style. Sometime, I wondered how to use some standard interface in java.util.function package with my real work software.

I have struggled longtime, even I started to use Java functional programming with Stream, Lambda Expression. I just awarded, it’s working the same without use all of them.

In this post, I will give an example why we should start to use java functional style with Java Predicate more and more in our real world software. Then I will show you the use case, between using the without and with Java Predicate.

Example:

Let’s talk about the example. Let’s say you have a requirements from the business:

They have the employee list which all the employee has name, age and gender.

The business would required and give the requirements to you below,

Find all employee who has salary more than 1000$ and gender equal Female

Find all employee who has salary less than or equal 1000$

Then we might come up with these:

Without Java Predicate

Requirement 1:

static List<Employee> findEmployeeCondition1(List<Employee> employees) {
List<Employee> foundEmployee = new ArrayList<>();
for (Employee employee : employees) {
if (employee.getSalary() > 1000 & employee.getGender().equals("Female")) {
foundEmployee.add(employee);
}
}
return foundEmployee;
}

Requirement 2:

static List<Employee> findEmployeeCondition2(List<Employee> employees) {
List<Employee> foundEmployee = new ArrayList<>();
for (Employee employee : employees) {
if (employee.getSalary() <= 1000) {
foundEmployee.add(employee);
}
}
return foundEmployee;
}

Main method:

public static void main(String[] args) {
List<Employee> employees = List.of(new Employee("Sara", 20, "Female", 3000),
new Employee("Dara", 31, "Male", 1000),
new Employee("Kimleng", 21, "Male", 500),
new Employee("Kanha", 25, "Male", 1500));
System.out.println(findEmployeeCondition1(employees));
System.out.println(findEmployeeCondition2(employees));
}

Result:

[Employee{name='Sara', age=20, gender='Female', salary=3000.0}]
[Employee{name='Dara', age=31, gender='Male', salary=1000.0}, Employee{name='Kimleng', age=21, gender='Male', salary=500.0}]

Yes that is working fine, absolutely if we are talking about functionality and the requirement they gave us. it’s passed… happy.

Next few day later, the product owner come back and ask you again. Hey, I would like you to enhance the existing functionality to find all the employee are gender equal Male.

Hmmm…. then you take around 15 minutes to think how can we enhance existing functions or create a new function for this requirement.

Then we might come up with this solution,

static List<Employee> findAllEmployeeAreMale(List<Employee> employees) {
List<Employee> foundEmployee = new ArrayList<>();
for (Employee employee : employees) {
if (employee.getGender().equals("Male")) {
foundEmployee.add(employee);
}
}
return foundEmployee;
}

Yeah this is great, it’s working now. However if you are looking back to your code, the amount of your code has been increasing time to time and you have to think what will be impact when the requirements are going to change more and more.

Start with Java Predicate

We can write the method something like this for using Java Predicate interface

static List<Employee> findEmployee(List<Employee> employees, Predicate<Employee> employeePredicate) {
List<Employee> foundEmployee = new ArrayList<>();
for (Employee employee : employees) {
if (employeePredicate.test(employee)){
foundEmployee.add(employee);
}
}
return foundEmployee;
}

Main method:

public static void main(String[] args) {
List<Employee> employees = List.of(new Employee("Sara", 20, "Female", 3000),
new Employee("Dara", 31, "Male", 1000),
new Employee("Kimleng", 21, "Male", 500),
new Employee("Kanha", 25, "Male", 1500));
;
// Condition 1
findEmployee(employees, employee -> employee.getSalary()>1000 & employee.getGender().equals("Female"));
// Condition 2
findEmployee(employees, employee -> employee.getSalary()<=1000 );
// Condition 3findEmployee(employees, employee -> employee.getGender().equals("Male"));}

That great, because amount of our codes is really concise and short.

Predicate<T> is a standard interface for java functional interface which have only one single abstract method test(T t) then return boolean.

With java functional interface, you can simply write with lambda expression. I will explain more on java lambda on next post more.

The benefits of Predicate here is, with Java Predicate it allows us to dynamically change the condition on run time and provides the flexibility to chose based what we want. If no predicate you might come back to change your existing code or adding more function.

So that is great for code maintainability and extensibility.

--

--

Soy Phea
Soy Phea

Written by Soy Phea

System Design, Scalability, Spring/Java, k8s

No responses yet