2020-04-25

Java Predicate Example – Predicate Filter

In mathematics, predicateUsually understood asboolean-valued function 'P: X? {true, false}' 'P: X? {true, false}', Called the predicate on X. You can think of it as an operator or function that returns trueor falsevalues.

Java 8 Predicates Usage
In Java 8, PredicateYesfunctional interface , So it can be used aslambda expressionOr the allocation target referenced by the method. So, what do you think, we can use these true / false return functions in daily programming? I will say that you can use predicates anywhere you need to evaluate conditions on groups / collections of similar objects so that evaluation can lead to true or false.

For example, you canrealtime usecasesUse caserealtime usecases

Find all children born after a certain date
Pizza set a specific time
Employees over a certain age, etc.
Java Predicate Class
therefore, java predicatesIt seems to be an interesting thing. Let's go deeper.

As I said, Predicateyesfunctional interface. This means that we can pass lambda expressions wherever we need predicates. For example, one such method isStreamfilter()Methods in the 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 the stream as a mechanism to create a sequence of elements that supports sequential and parallel aggregation operations. This means that we can collect and perform certain operations on all elements present in the stream at any time with one call.

So, essentially, we can use streams and predicates to –

First filter certain elements from the group, then
Then perform some operations on the filtered elements.
Using Predicate on a collection
To demonstrate, we have a Employeeclass as follows:


Employee.java

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 when needed. So far, so good. So far, I have beenEmployeePredicates.javaThe above three methods are included:

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 will see that I created another utility methodfilterEmployees()To showjava predicate filter. Basically it makes the code neat and reduces duplication. You can also write multiple predicates to formpredicate chain , Just like inbuilder patternDid that.

Therefore, in this function, we pass the employeeslist, and pass the predicate, then this function will return to meetparameter predicateNew employeescollection of mentioned conditions .


TestEmployeePredicates.java

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]
The predicate is indeed a very good addition in Java 8, I will use it whenever possible.

Final Thoughts on Predicates in Java 8
They move your conditions (sometimes business logic) to a central location. This helps to unit test them separately.
No need to copy any changes to multiple locations. Java predicates improve code maintenance.
Compared with writing if-else blocks, code such as "filterEmployees (employees, isAdultFemale ())" is more readable.
Okay, these are my thoughts in Java 8 predicates. What do you think of this feature? Share with all of us in the comments section.

No comments:

Post a Comment