How do you group first and then apply filtering using Java streams?
Example: Consider this Employee
class: I want to group by Department with a list of an employee having a salary greater than 2000.
public class Employee { private String department; private Integer salary; private String name; //getter and setter public Employee(String department, Integer salary, String name) { this.department = department; this.salary = salary; this.name = name; } }
This is how I can do this
List<Employee> list = new ArrayList<>(); list.add(new Employee("A", 5000, "A1")); list.add(new Employee("B", 1000, "B1")); list.add(new Employee("C", 6000, "C1")); list.add(new Employee("C", 7000, "C2")); Map<String, List<Employee>> collect = list.stream() .filter(e -> e.getSalary() > 2000) .collect(Collectors.groupingBy(Employee::getDepartment));
Output
{A=[Employee [department=A, salary=5000, name=A1]], C=[Employee [department=C, salary=6000, name=C1], Employee [department=C, salary=7000, name=C2]]}
As there are no employees in Department B with a salary greater than 2000. So there is no key for Department B: But actually, I want to have that key with empty list –
Expected output
{A=[Employee [department=A, salary=5000, name=A1]], B=[], C=[Employee [department=C, salary=6000, name=C1], Employee [department=C, salary=7000, name=C2]]}
How can we do this?
1. Overview. In this tutorial, We'll learn how to utilise stream filter() with several filter conditions (can be more than one condition). Normally, we apply a single condition to streams using filter() method with lambda and then store the results in Lists or Sets.
Java stream provides a method filter() to filter stream elements on the basis of given predicate. Suppose you want to get only even elements of your list then you can do this easily with the help of filter method. This method takes predicate as an argument and returns a stream of consisting of resulted elements.
The java.io package provides a set of abstract classes that define and partially implement filter streams. A filter stream filters data as it's being read from or written to the stream. The filter streams are FilterInputStream or FilterOutputStream , FilterInputStream , and FilterOutputStream. .
The groupingBy() method of Collectors class in Java are used for grouping objects by some property and storing results in a Map instance. In order to use it, we always need to specify a property by which the grouping would be performed. This method provides similar functionality to SQL's GROUP BY clause.
You can make use of the Collectors.filtering
API introduced since Java-9 for this:
Map<String, List<Employee>> output = list.stream() .collect(Collectors.groupingBy(Employee::getDepartment, Collectors.filtering(e -> e.getSalary() > 2000, Collectors.toList())));
Important from the API note :
The filtering() collectors are most useful when used in a multi-level reduction, such as downstream of a
groupingBy
orpartitioningBy
.A filtering collector differs from a stream's
filter()
operation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With