说,我有一个名为Project的课程,
class Project {
private String projectId;
private String projectName;
}
和一个名为Employee的类,它有一个项目列表
class Employee {
private String name;
private List<Project> projects
}
我还有一个Employee对象列表。现在,我需要创建一个Map,其中项目列表作为键,一组员工对象作为此列表中的值。我可以通过
来实现它Map<List<Project>, Set<Employee>> x =
employees
.stream
.collect(Collectors.groupingBy(Employee::getProjects, Collectors.toSet()));
但是,由于我使用List作为键,我想要格外小心并确保列表是不可变的。有没有办法实现这个目标?
感谢。
答案 0 :(得分:2)
Java 9支持列表不变性。您只需将Employee#getProjects
更改为以下内容:
public List<Project> getProjects() {
return List.of(projects.toArray(new Project[projects.size()]));
}
如果您不希望此方法返回不可变List
,那么您可以更改Collector
:
employees.stream()
.collect(Collectors.groupingBy(e -> List.of(e.getProjects().toArray(new Project[0])), Collectors.toSet()));
答案 1 :(得分:1)
如果我没有遗漏这里显而易见的事情,你不能简单地将其包含在Collections.unmodifiableList
中:
collect(Collectors.groupingBy(
emps -> Collections.unmodifiableList(emps.getProjects()),
Collectors.toSet());
如果您在类路径上有guava
,则可以使用ImmutableList
答案 2 :(得分:0)
这就是你用Guava做的事情(我试用了版本24.1,这是迄今为止的最新版本)
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()));
这假设您的类定义是这些(我需要为原始示例添加getProjects方法进行编译):
class Project {
public String projectId;
public String projectName;
}
class Employee {
public String name;
public List<Project> projects;
public List<Project> getProjects() {
return projects;
}
}
答案 3 :(得分:-1)
您可以使用
private List<? extends Project> projects = new LinkedList<>();
填充员工时。它建立了一个逻辑上不可变的列表。
答案 4 :(得分:-1)
如果您不介意将地图初始存储在可变地图中,然后将其复制到不可变集合中,则可以执行以下操作:
ImmutableMap<List<Project>, List<Employee>> collect = employees.stream()
.collect(Collectors.collectingAndThen(Collectors.groupingBy(Employee::getProjects),
ImmutableMap::copyOf));
ImmutableMap是Google Common的结构( com.google.common.collect.ImmutableMap )。也归功于this。