1. Overview
In this quick tutorial, we’ll learn how to find items from one list based on values from another list using Java 8 Streams.
2. Setting Up Entities
Let’s start with two entity classes – Employee and Department:
class Employee {
Integer employeeId;
String employeeName;
// getters and setters
}
class Department {
Integer employeeId;
String department;
// getters and setters
}
3. Filter for Objects Including Specific List of Values
The idea here is to filter a list of Employee objects based on a list of Department objects. More specifically, we want to find all Employees from a list that:
- have “sales” as their department and
- have a corresponding employeeId in a list of Departments
To achieve this, we filter one inside the other:
@Test
public void givenDepartmentList_thenEmployeeListIsFilteredCorrectly() {
Integer expectedId = 1002;
populate(emplList, deptList);
List<Employee> filteredList = emplList.stream()
.filter(empl -> deptList.stream()
.anyMatch(dept ->
dept.getDepartment().equals("sales") &&
empl.getEmployeeId().equals(dept.getEmployeeId())))
.collect(Collectors.toList());
assertEquals(1, filteredList.size());
assertEquals(expectedId, filteredList.get(0)
.getEmployeeId());
}
After populating both lists, we simply pass a Stream of Employee objects to the Stream of Department objects.
Next, to filter records based on our two conditions, we’re using the anyMatch predicate, inside which we have combined all the given conditions.
Finally, we collect the result into filteredList.
4. Filter for Objects Excluding Specific List of Values
Let’s continue with the same theme, but this time filter a list of Department objects based on a list of Employee objects to exclude. More specifically, we want to find all Departments from a list that exclude Employees corresponding to a list of employeeIds.
Further, these employeeIds exclude all employees from the “sales” department. To achieve this, we filter departments by excluding employee IDs from a second list employeeIdList:
@Test
public void givenEmployeeListToExclude_thenDepartmentListIsFilteredCorrectly() {
String expectedDepartment = "sales";
List<Integer> employeeIdList = Arrays.asList(1001, 1002, 1004, 1005);
populate(employeeList, departmentList);
List<Department> filteredList = departmentList.stream()
.filter(dept -> !employeeIdList.contains(dept.getEmployeeId()))
.collect(Collectors.toList());
assertNotEquals(expectedDepartment, department.getDepartment());
}
After populating both lists, we create a Stream of Department objects and filter records based on the employeeIdList to exclude.
Finally, we collect the result into filteredList.
5. Conclusion
In this article, we learned how to:
- stream values of one list into the other list using Collection#stream and
- combine multiple filter conditions using the anyMatch() predicate
- discuss examples to include or exclude objects in one list based on objects in a second list
The full source code of this example is available over on GitHub.