Core Java

Filter a List by Any Matching Field

Java 8 introduced the powerful Stream API, making it easier to process collections in a functional programming style. Let us delve into understanding how to filter a list in Java by any matching field.

1. Using the Stream.filter() Method

The Stream.filter() method allows us to filter elements in a collection based on a given predicate. Here’s an example of filtering a list of objects based on a specific field.

import java.util.*;
import java.util.stream.Collectors;

class Employee {
    private String name;
    private String department;
    private int age;

    public Employee(String name, String department, int age) {
        this.name = name;
        this.department = department;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public String getDepartment() {
        return department;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Employee{name='" + name + "', department='" + department + "', age=" + age + "}";
    }
}

public class FilterExample {
    public static void main(String[] args) {
        List<Employee> employees = Arrays.asList(
            new Employee("Alice", "HR", 30),
            new Employee("Bob", "IT", 25),
            new Employee("Charlie", "Finance", 28),
            new Employee("Diana", "IT", 35)
        );

        // Filter employees by department "IT"
        List<Employee> filteredEmployees = employees.stream()
            .filter(e -> "IT".equals(e.getDepartment()))
            .collect(Collectors.toList());

        filteredEmployees.forEach(System.out::println);
    }
}

1.1 Code explanation and output

The code defines a simple Java application that demonstrates how to filter a list of objects using the Stream API introduced in Java 8. The Employee class represents an employee with three fields: name, department, and age. It includes a constructor for initializing these fields, getter methods for accessing their values, and an overridden toString() method to provide a readable string representation of the object.

In the FilterExample class, the main method creates a list of Employee objects using Arrays.asList(). This list contains four employees with different names, departments, and ages. The program then uses the Stream.filter() method to filter the list of employees and retain only those who belong to the “IT” department.

The filtering operation is performed using a lambda expression: e -> "IT".equals(e.getDepartment()). This predicate checks if the department field of an Employee object matches the string “IT”. The filtered employees are collected into a new list using Collectors.toList().

Finally, the program iterates through the filtered list using the forEach method and prints each Employee object to the console. The output consists of the details of all employees whose department is “IT”.

Employee{name='Bob', department='IT', age=25}
Employee{name='Diana', department='IT', age=35}

2. Creating a String Representation for Filtering

Sometimes, we may want to filter based on multiple fields by combining them into a single-string representation. This approach simplifies the predicate logic.

public class FilterExample {
    public static void main(String[] args) {
        List<Employee> employees = Arrays.asList(
            new Employee("Alice", "HR", 30),
            new Employee("Bob", "IT", 25),
            new Employee("Charlie", "Finance", 28),
            new Employee("Diana", "IT", 35)
        );

        // Filter employees with the substring "IT" in their string representation
        List<Employee> filteredEmployees = employees.stream()
            .filter(e -> (e.getName() + " " + e.getDepartment()).toLowerCase().contains("it"))
            .collect(Collectors.toList());

        filteredEmployees.forEach(System.out::println);
    }
}

2.1 Code explanation and output

The provided code is a Java program that filters a list of employees based on whether a specified substring (“IT”) exists in a concatenated string representation of their name and department. The program leverages the Stream API introduced in Java 8.

Inside the main method, a list of Employee objects is created using Arrays.asList(). Each Employee object represents an employee with attributes like name, department, and age. In this example, the list includes four employees with different values for these attributes.

The filtering operation is performed on this list using the Stream.filter() method. For each employee in the list, the filter method combines the name and department fields into a single string using e.getName() + " " + e.getDepartment(). This combined string is then converted to lowercase using the toLowerCase() method to make the search case-insensitive.

The .contains("it") method checks if the combined string contains the substring “it”. If it does, the employee is included in the filtered result. The filtered employees are then collected into a new list using Collectors.toList().

Finally, the forEach method is used to iterate over the filtered list, and the System.out.println statement prints each matching Employee object to the console. The output consists of employees whose name or department includes the substring “IT”, regardless of case.

Employee{name='Bob', department='IT', age=25}
Employee{name='Diana', department='IT', age=35}

3. Creating a General Full-Text Search Method

To make filtering more generic, we can create a method that accepts a search term and matches it against all fields of an object.

public class FilterExample {
    public static void main(String[] args) {
        List<Employee> employees = Arrays.asList(
            new Employee("Alice", "HR", 30),
            new Employee("Bob", "IT", 25),
            new Employee("Charlie", "Finance", 28),
            new Employee("Diana", "IT", 35)
        );

        // General full-text search
        String searchTerm = "Bob";
        List<Employee> filteredEmployees = employees.stream()
            .filter(e -> fullTextSearch(e, searchTerm))
            .collect(Collectors.toList());

        filteredEmployees.forEach(System.out::println);
    }

    private static boolean fullTextSearch(Employee employee, String term) {
        String allFields = String.format("%s %s %d", employee.getName(), employee.getDepartment(), employee.getAge());
        return allFields.toLowerCase().contains(term.toLowerCase());
    }
}

3.1 Code explanation and output

The provided code is a Java program that demonstrates how to implement a general full-text search on a list of objects. It allows filtering of objects based on whether a specified search term matches any field value of the object, using Java 8’s Stream API.

In the main method, a list of Employee objects is created using Arrays.asList(). Each Employee object represents an individual with attributes like name, department, and age. The list contains four employees with diverse attributes.

The program defines a search term, searchTerm, with the value “Bob”. The goal is to find employees whose details include this term in any field (e.g., name, department, or age). The Stream.filter() method is used to process the list of employees. It calls a helper method, fullTextSearch, for each employee.

The fullTextSearch method takes an Employee object and a search term as input. It concatenates all the fields of the employee into a single string using String.format(), creating a unified text representation of the employee. This string is converted to lowercase to ensure the search is case-insensitive.

The method checks if the search term (also converted to lowercase) is contained within the concatenated string using .contains(). If the term is found, the method returns true, indicating that the employee should be included in the filtered results.

The filtered list of employees is collected using Collectors.toList() and printed to the console using forEach. The output consists of all employees whose name, department, or age matches the search term.

Employee{name='Bob', department='IT', age=25}

4. Conclusion

Java 8’s Stream API provides powerful tools for filtering collections. By using methods like Stream.filter(), creating string representations, or implementing general full-text search methods, we can easily filter lists based on any matching field. These approaches help make code more readable and maintainable.

Yatin Batra

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button