Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Collections - Filtering on values in nested list

I'm new to Java 8 and the Stream API.

If I have a list of Employee objects:

List<Employee> employees;

public class Employee {
    private String name;
    private List<Project> involvedInProjects;
}

public class Project {
    private int projectId;
}

I want to filter on employees beeing involved in certain projects, how would I go about doing this with the stream API in java 8?

Would it be easier if I had a Map where the key was an unique employeeID, instead of a List?

like image 996
sjallamander Avatar asked Nov 19 '15 18:11

sjallamander


2 Answers

So you can get access to the nested list inside of a stream operation and then work with that. In this case we can use a nested stream as our predicate for the filter

employees.stream().filter(
employee -> employee.involvedInProjects.stream()
.anyMatch(proj -> proj.projectId == myTargetId ))

This will give you a stream of all of the employees that have at least one project matching you targetId. From here you can operate further on the stream or collect the stream into a list with .collect(Collectors.toList())

like image 124
Gene Taylor Avatar answered Jan 03 '23 12:01

Gene Taylor


If you don't mind modifying the list in place, you can use removeIf and the predicate you will give as parameter will check if the projects where an employee is involved does not match the given id(s).

For instance,

employees.removeIf(e -> e.getInvolvedInProjects().stream().anyMatch(p -> p.getProjectId() == someId));

If the list does not support the removal of elements, grab the stream from the employees list and filter it with the opposite predicate (in this case you could use .noneMatch(p -> p.getProjectId() == someId)) as in removeIf and collect the result using Collectors.toList().

like image 40
Alexis C. Avatar answered Jan 03 '23 10:01

Alexis C.