Say, I've a class called Project,
class Project {
private String projectId;
private String projectName;
}
and a class called Employee, which has a list of projects
class Employee {
private String name;
private List<Project> projects
}
I also have a list of Employee objects. Now, I need to create a Map with the list of projects as the key and a set of employee objects as the value from this list. I can get it working by
Map<List<Project>, Set<Employee>> x =
employees
.stream
.collect(Collectors.groupingBy(Employee::getProjects, Collectors.toSet()));
However, since I'm using List as the key, I want to be extra careful and make sure that the list is immutable. Is there a way to achieve this?
Thanks.
This is how you would do it with Guava (I tried it with version 24.1, which is the latest one as of today)
List<Employee> employees = new ArrayList<>();
// ... let's assume someone fills in the employees
// Everything mutable
Map<List<Project>, Set<Employee>> x =
employees
.stream()
.collect(Collectors.groupingBy(Employee::getProjects, Collectors.toSet()));
// Everything immutable
ImmutableMap<ImmutableList<Project>, ImmutableSet<Employee>> immutableX =
employees
.stream()
.collect(
Collectors.collectingAndThen(
Collectors.groupingBy(
(employee) -> ImmutableList.copyOf(employee.getProjects()),
ImmutableSet.<Employee>toImmutableSet()),
ImmutableMap::copyOf));
// Only the List<Project> immutable
Map<ImmutableList<Project>, Set<Employee>> immutableListX =
employees
.stream()
.collect(
Collectors.groupingBy(
(employee) -> ImmutableList.copyOf(employee.getProjects()),
Collectors.toSet()));
This assumes your classes definitions are these (I needed to add the method getProjects for the original example to compile):
class Project {
public String projectId;
public String projectName;
}
class Employee {
public String name;
public List<Project> projects;
public List<Project> getProjects() {
return projects;
}
}
List immutability is supported in Java 9. You can simply change Employee#getProjects
to the following:
public List<Project> getProjects() {
return List.of(projects.toArray(new Project[projects.size()]));
}
If you don't want this method to return an immutable List
, then you can change the Collector
:
employees.stream()
.collect(Collectors.groupingBy(e -> List.of(e.getProjects().toArray(new Project[0])), Collectors.toSet()));
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