Filter Pattern in Java


The Filter Design Pattern, also known as the Criteria Design Pattern, is a structural design pattern used by developers to filter objects based on different criteria. It enables decoupled filtering and logical operations by chaining multiple criteria into a single criterion.

It provides two techniques for creating filters: filtering for the entire collection or filtering for a particular collection member.

To apply criteria to a class, you can follow these steps:

  • Create a class that requires filtering.

  • Develop the criteria's interface.

  • Implement concrete classes that meet the interface's requirements.

  • Filter out certain objects by using a variety of criteria and their combinations.

  • Check the output to make sure the intended filtering result was obtained.

How to implement

To implement the Filter Design Pattern, you can follow these steps:

  • Create a class called "Person" to indicate the filtered object.

  • Design an interface named "Criteria" to define the filtering criteria.

  • Implement concrete classes that satisfy the "Criteria" interface to specify different filtering conditions.

  • Filter a list of "Person" objects using the "Criteria" objects by selecting different criteria and combining them.

  • Develop a demo class named "CriteriaPatternDemo" to showcase the usage of the filter pattern by applying different criteria to filter the list of "Person" objects.

By following these steps, you can effectively apply the Filter Design Pattern to filter objects based on specified criteria.

Step 1

To start implementing the Filter Design Pattern, we can create a class to which the criteria will be applied.

Let's name this class "Person.java". This class will act as the object on which the filtering criteria will depend.

Syntax 1

The below code sample creates the "Person" class as well as three private example variables. We have named them "name," "genderType," and "maritalStatus."

The class includes methods for obtaining the values of these variables. It also includes a constructor for initialising them.

public class Tutorialspoint {
	
   private String name;
   private String genderType;
   private String maritalStatus;

   public Person(String name, String genderType, String maritalStatus){
      this.name = name;
      this.gender = genderType;
      this.maritalStatus = maritalStatus;		
   }

   public String getName() {
      return name;
   }
   public String getGenderType() {
      return gender;
   }
   public String getMaritalStatus() {
      return maritalStatus;
   }	
}

Step 2

The following action is to develop an interface for the criteria in order to move forward with carrying out the Filter Design Pattern. This interface will define the methods that the concrete criteria classes will implement.

Syntax 2

The sample code given illustrates how to create the "Criterion" interface.

A list of "Person" object inputs are accepted by the interface's "meetCriteria" method. It is designed to return a filtered list of "Person" objects that comply with the specified criteria.

import java.util.List;

public interface Criterion {
   public List<Person> meetCriteria(List<Person> persons);
}

Step 3

Making legitimate classes implementing the Criteria interface is the next stage in putting the Filter Design Pattern into practise. As an illustration, let's construct a class called "CriteriaMale.java".

Step 4

To implement the Filter Design Pattern, the next step is to create concrete classes that implement the Criteria interface. We can create a class named "CriteriaMale.java" as an example. There are other classes that provide concrete implementations for filtering criteria such as "Female," "Single," combining criteria using "And," and combining criteria using "Or."

Step 5

To filter out persons using different criteria and their combinations, the code provides the following implementation.

Example 1

A list of Person objects is created in the CriteriaPatternDemo class, and the list is filtered using several criteria, including "male," "female," "single," "singleMale," and "singleOrFemale."

The output is then printed for each filtered criteria combination, demonstrating the effectiveness of the Filter Design Pattern.

import java.util.ArrayList;
import java.util.List;

interface Criteria {
   List<Person> meetCriteria(List<Person> persons);
}

class CriteriaMale implements Criteria {
   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> malePersons = new ArrayList<Person>();
      for (Person person : persons) {
         if (person.getGender().equalsIgnoreCase("Male")) {
            malePersons.add(person);
         }
      }
      return malePersons;
   }
}

class CriteriaFemale implements Criteria {
   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> femalePersons = new ArrayList<Person>();
      for (Person person : persons) {
         if (person.getGender().equalsIgnoreCase("Female")) {
            femalePersons.add(person);
         }
      }
      return femalePersons;
   }
}

class CriteriaSingle implements Criteria {
   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> singlePersons = new ArrayList<Person>();
      for (Person person : persons) {
         if (person.getMaritalStatus().equalsIgnoreCase("Single")) {
            singlePersons.add(person);
         }
      }
      return singlePersons;
   }
}

class AndCriteria implements Criteria {
   private Criteria criteria;
   private Criteria otherCriteria;

   public AndCriteria(Criteria criteria, Criteria otherCriteria) {
      this.criteria = criteria;
      this.otherCriteria = otherCriteria;
   }

   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> firstCriteriaPersons = criteria.meetCriteria(persons);
      return otherCriteria.meetCriteria(firstCriteriaPersons);
   }
}

class OrCriteria implements Criteria {
   private Criteria criteria;
   private Criteria otherCriteria;

   public OrCriteria(Criteria criteria, Criteria otherCriteria) {
      this.criteria = criteria;
      this.otherCriteria = otherCriteria;
   }

   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> firstCriteriaItems = criteria.meetCriteria(persons);
      List<Person> otherCriteriaItems = otherCriteria.meetCriteria(persons);

      for (Person person : otherCriteriaItems) {
         if (!firstCriteriaItems.contains(person)) {
            firstCriteriaItems.add(person);
         }
      }
      return firstCriteriaItems;
   }
}

class Person {
   private String name;
   private String gender;
   private String maritalStatus;

   public Person(String name, String gender, String maritalStatus) {
      this.name = name;
      this.gender = gender;
      this.maritalStatus = maritalStatus;
   }

   public String getName() {
      return name;
   }

   public String getGender() {
      return gender;
   }

   public String getMaritalStatus() {
      return maritalStatus;
   }
}

public class CriteriaPatternExample {
   public static void main(String[] args) {
      List<Person> persons = new ArrayList<Person>();

      persons.add(new Person("Benny", "Male", "Single"));
      persons.add(new Person("Johnny", "Male", "Married"));
      persons.add(new Person("Anna", "Female", "Married"));
      persons.add(new Person("Emma", "Female", "Single"));
      persons.add(new Person("Michael", "Male", "Single"));
      persons.add(new Person("Anthony", "Male", "Single"));

      Criteria male = new CriteriaMale();
      Criteria female = new CriteriaFemale();
      Criteria single = new CriteriaSingle();
      Criteria singleMale = new AndCriteria(single, male);
      Criteria singleOrFemale = new OrCriteria(single, female);

      System.out.println("Males: ");
      printPersons(male.meetCriteria(persons));

      System.out.println("\nFemales: ");
      printPersons(female.meetCriteria(persons));

      System.out.println("\nSingle Males: ");
      printPersons(singleMale.meetCriteria(persons));

      System.out.println("\nSingle Or Females: ");
      printPersons(singleOrFemale.meetCriteria(persons));
   }

   public static void printPersons(List<Person> persons) {
      for (Person person : persons) {
         System.out.println("Person: [ Name: " + person.getName() + ", Gender: " + person.getGender() + ", Marital Status: " + person.getMaritalStatus() + " ]");
      }
   }
}

Output

The output verifies that the filtering, depending on different criteria and their combinations, works correctly, resulting in the desired subsets of persons being displayed.

Males: 
Person : [ Name : Benny, Gender : Male, Marital Status : Single ]
Person : [ Name : Johnny, Gender : Male, Marital Status : Married ]
Person : [ Name : Michael, Gender : Male, Marital Status : Single ]
Person : [ Name : Anthony, Gender : Male, Marital Status : Single ]

Females: 
Person : [ Name : Anna, Gender : Female, Marital Status : Married ]
Person : [ Name : Emma, Gender : Female, Marital Status : Single ]

Single Males: 
Person : [ Name : Benny, Gender : Male, Marital Status : Single ]
Person : [ Name : Michael, Gender : Male, Marital Status : Single ]
Person : [ Name : Anthony, Gender : Male, Marital Status : Single ]

Single Or Females: 
Person : [ Name : Benny, Gender : Male, Marital Status : Single ]
Person : [ Name : Emma, Gender : Female, Marital Status : Single ]
Person : [ Name : Michael, Gender : Male, Marital Status : Single ]
Person : [ Name : Anthony, Gender : Male, Marital Status : Single ]
Person : [ Name : Anna, Gender : Female, Marital Status : Married ]

Conclusion

Filter Design Pattern is also called the Criteria Design Pattern. By creating a class to be filtered, designing an interface for the criteria, implementing concrete classes for different criteria, and using combinations of criteria, developers can effectively filter objects.

The Filter Design Pattern offers a versatile approach to filtering collections and individual members within them, allowing for dynamic and customizable filtering operations.

Updated on: 11-Jul-2023

119 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements