【发布时间】:2017-09-26 08:42:23
【问题描述】:
给定一个类Item:
public class Item {
private String field1;
private String field2;
private String field3;
private Integer field4;
// getters, constructor...
}
还有另一个类Group(field1和field2存储Item的等价字段):
public class Group {
private String field1;
private String field2;
}
我有一个List<Item>,我需要将其聚合成以下结构的地图:
Map<Group, Map<Field3, List<Field4>>>
示例数据:
Field1 | Field2 | Field3 | Field4
------ | ------ | ------ | ------
"f1" | "f2" | "a" | 1
"f1" | "f2" | "a" | 2
"f1" | "f2" | "a" | 3
"f1" | "f2" | "b" | 4
"f1" | "f2" | "b" | 5
"f1" | "f2" | "c" | 6
"f1a" | "f2a" | "a" | 7
"f1a" | "f2a" | "a" | 8
预期结果如下:
Group(field1=f1a, field2=f2a)={b=[7, 8]}, Group(field1=f1, field2=f2)={a=[1, 2, 3], b=[4, 5], c=[6]}
到目前为止,我已经能够通过 Field1、Field2 和 Field3 进行聚合,这样我就有了以下结构(其中GroupEx 代表一个包含 Field1、Field2 和 Field3 的 POJO):
Map<GroupEx, List<Field4>>
这样聚合的代码是:
Map<GroupEx, List<Integer>> aggregated = items.stream()
.collect(Collectors.groupingBy(item -> new GroupEx(x.getField1(), x.getField2(), x.getField3())
, Collectors.mapping(Item::getField4, Collectors.toList())));
我正在努力获得正确的语法,以允许我按 Field1 和 Field2 分组,然后按我需要的方式按 Field3 和 Field4 分组到地图中。
“长手”语法是:
Map<Group<String, String>, Map<String, List<Integer>>> aggregated = new HashMap<>();
for (Item item : items) {
Group key = new Group(item.getField1(), item.getField2());
Map<String, List<Integer>> field3Map = aggregated.get(key);
if (field3Map == null) {
field3Map = new HashMap<>();
aggregated.put(key, field3Map);
}
List<Integer> field4s = field3Map.get(item.getField3());
if (field4s == null) {
field4s = new ArrayList<>();
field3Map.put(item.getField3(), field4s);
}
field4s.add(item.getField4());
}
有人能告诉我如何实现我的目标分组吗?
【问题讨论】:
标签: java java-8 java-stream