Java Stream filter() method

Introduction

The filter method in Java Streams allows you to create a new stream consisting of elements that meet specific criteria. It operates on the principle of predicate functions, where you define a condition, and the filter method includes only the elements that satisfy that condition in the resulting stream.

Syntax: The filter() method takes a Predicate as an argument, which is a functional interface that represents a boolean-valued test. The predicate is applied to each element in the stream, and if the predicate returns true, the element is included in the resulting stream. Otherwise, the element is discarded.

				
					Stream<T> filter(Predicate<? super T> predicate)

				
			

Practical Use Case

Filtering a List of Employees: Imagine you have a list of employee objects, and you want to filter out only the employees who are earning above a certain salary threshold. Instead of using traditional loops and conditional statements, let’s leverage the power of Java Streams.

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

class Employee {
    String name;
    double salary;

    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }
    
        @Override
    public String toString() {
        return new StringJoiner(", ", Employee.class.getSimpleName() + "[", "]")
                .add("name='" + name + "'")
                .add("salary=" + salary)
                .toString();
    }
}

public class StreamFilterExample {

    public static void main(String[] args) {
        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee("Alice", 60000));
        employees.add(new Employee("Bob", 75000));
        employees.add(new Employee("Charlie", 90000));
        employees.add(new Employee("David", 55000));

        // Using Java Streams to filter employees with salary > 70000
        List<Employee> highEarners = employees.stream()
                .filter(employee -> employee.getSalary() > 70000)
                .toList();

        // Displaying the results
        System.out.println("High-Earning Employees:");
        highEarners.forEach(employee ->
                System.out.println("Name: " + employee.getName() + ", Salary: $" + employee.getSalary()));
    }
}

				
			
				
					// Output
High-Earning Employees:
Name: Bob, Salary: $75000.0
Name: Charlie, Salary: $90000.0
				
			

Example 1: Filtering Employees by Name
Suppose you want to filter employees whose names start with the letter ‘A’. Here’s how you can achieve this using the filter method:

				
					// Filtering employees by name starting with 'A'
List<Employee> aEmployees = employees.stream()
        .filter(employee -> employee.getName().startsWith("A"))
        .toList();
System.out.println(aEmployees);
				
			
				
					// Output
[Employee[name='Alice', salary=60000.0]]

				
			

Example 2: Filtering Employees by Salary Range

Let’s say you want to find employees whose salaries fall within a specific range, for instance, between $60,000 and $80,000:

				
					// Filtering employees by salary range ($60,000 to $80,000)
List<Employee> midRangeEarners = employees.stream()
        .filter(employee -> employee.getSalary() >= 60000 && employee.getSalary() <= 80000)
        .toList();
        
System.out.println(midRangeEarners);


				
			
				
					// Output

[Employee[name='Alice', salary=60000.0], Employee[name='Bob', salary=75000.0]]

				
			

Example 3: Using Combined Filters

You can also combine multiple filters using the filter method. For example, let’s find employees whose names start with ‘D’ and have a salary greater than $50,000:

				
					        // Filtering employees by name starting with 'D' and salary > $50,000
        List<Employee> specificEmployees = employees.stream()
                .filter(employee -> employee.getName().startsWith("D") && employee.getSalary() > 50000)
                .toList();
        System.out.println(specificEmployees);
				
			
				
					// Output
[Employee[name='David', salary=55000.0]]

				
			

Conclusion

Java Streams, with its filter method, offers a powerful and expressive way to manipulate collections of data. By leveraging functional programming concepts, developers can write clean, readable, and efficient code. In our practical example, we showcased how the filter method can be used to streamline the process of extracting specific elements from a collection based on a given condition.