2 回答
TA贡献1863条经验 获得超2个赞
您最需要寻找的是嵌套分组,例如:
Map<String, Map<String, List<Employee>>> groupedMap = employees.stream()
.collect(Collectors.groupingBy(Employee::getName,
Collectors.groupingBy(Employee::getDomain, Collectors.toList())));
注- 这些值是List<Employee>按姓名分组的员工,然后按域分组的员工。(两者都同样加入到一个列表中。)
如果您严格遵守让单个员工与指定的分组相对应,那么只需稍作修改,代码就对我来说非常有效:
Map<String, Map<String, Employee>> groupedReducedMap = employees.stream()
.collect(Collectors.groupingBy(Employee::getName,
Collectors.toMap(Employee::getDomain,
Function.identity(), // value as the employee instance
(a, b) -> a))); // choose first instance for similar 'domain'
TA贡献1780条经验 获得超1个赞
由于输出应该是Map<String, Map<String,Employee>>而不是Map<String, Map<String,List<Employee>>>(即根据您请求的输出,不能有两个Employee具有相同名称和相同域的 s),您可以链接两个groupingBy,然后使用它reducing来确保每个内部组将有一个Employee而不是一个List<Employee>:
Map<String, Map<String,Optional<Employee>>> output =
e.stream()
.collect(Collectors.groupingBy(Employee::getName,
Collectors.groupingBy(Employee::getDomain,
Collectors.reducing((x1,x2)->x2))));
这个版本的问题reducing是它返回一个Optional<Employee>而不是Employee,即使我们知道Optional永远不会为空。
我们可以通过以下方式解决这个问题:
Map<String, Map<String,Employee>> output =
e.stream()
.collect(Collectors.groupingBy(Employee::getName,
Collectors.groupingBy(Employee::getDomain,
Collectors.reducing(e.get(0),
(x1,x2)->x2))));
现在,我们使用具有标识值的变体reducing,向其传递任意Employee实例(哪个实例并不重要,因为它总是会被正确的实例替换)。
添加回答
举报