首先,提到的 POJO 类 Pojo4 和 Pojo3 需要实现 hashCode 和 equals 才能用作映射键以及属性的相关 getter。
转换应该使用常见的Collectors.groupingBy / Collectors.mapping 收集器,并且需要初始重新映射到包含两个对象的普通容器,例如Pair。
以下示例使用 Java 11 Map.entry 作为中间容器。
static Map<Pojo4, <Map<Pojo3, List<Pojo2>>>> convert(Stream<Pojo1> ones) {
return ones // Stream<Pojo1>
.map(Pojo1::getItem) // Stream<Pojo2>
.map(p2 -> Map.entry(p2, p2.getItem())) // Stream<Map.Entry<Pojo2, Pojo3>>
.collect(Collectors.groupingBy(
me -> me.getValue().getItem(), // key: Pojo4
Collectors.groupingBy(
me -> me.getValue(), // key: Pojo3
Collectors.mapping(
Map.Entry::getKey, Collectors.toList()
)
)
));
}
同样,排序版本可以使用Collectors.groupingBy 和地图供应商来实现;另外List<Pojo2> 应该使用collectingAndThen 进行排序。
假设Pojo2、Pojo3、Pojo4 有getter getField 对属性进行排序,则提供以下更新:
static Map<Pojo4, <Map<Pojo3, List<Pojo2>>>> convert(Stream<Pojo1> ones) {
return ones
.map(Pojo1::getItem) // Stream<Pojo2>
.map(p2 -> Map.entry(p2, p2.getItem())) // Stream<Map.Entry<Pojo2, Pojo3>>
.collect(Collectors.groupingBy(
me -> me.getValue().getItem(), // key: Pojo4
() -> new TreeMap(Comparator.comparing(Pojo4::getField)),
Collectors.groupingBy(
me -> me.getValue(), // key: Pojo3
() -> new TreeMap(Comparator.comparing(Pojo3::getField)),
Collectors.mapping(
Map.Entry::getKey, Collectors.collectingAndThen(
Collectors.toList(), // List<Pojo2>
list -> {
list.sort(Comparator.comparing(Pojo2::getField));
return list;
}
)
)
)
));
}
免责声明:上面的代码示例尚未经过测试,因此可能需要进行额外的调整。