gpt4 book ai didi

java - 使用 Java 8 流的复杂聚合

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:21:51 25 4
gpt4 key购买 nike

给定一个类 Item:

public class Item {
private String field1;
private String field2;
private String field3;
private Integer field4;

// getters, constructor...
}

还有另一个类组(field1 和 field2 存储来自 Item 的等效字段):

public class Group {
private String field1;
private String field2;
}

我有一个 List<Item>我需要将其聚合成以下结构的 map :

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 中。

“长手”语法是:

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());
}

有人能告诉我如何实现我的目标分组吗?

最佳答案

这是 downstream collectors 的位置功能派上用场。

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;

...

List<Item> list = ....
Map<Group, Map<String, List<Integer>>> map =
list.stream().collect(groupingBy(i -> new Group(i.getField1(), i.getField2()),
groupingBy(Item::getField3, mapping(Item::getField4, toList()))));

首先,您按 Group 对项目进行分组字段(此时你是一个 Map<Group, List<Item>>),然后你将每个值(List<Item>)再次映射到一个映射,你在其中按字段 3(Map<Group, Map<Field3, List<Item>>)分组。

然后您将第二个映射中的值映射到 field4 并将它们收集到一个列表中,最终得到一个 Map<Group, Map<Field3, List<Field4>> .

根据您的输入,它输出:

{Group{field1='f1a', field2='f2a'}={a=[7, 8]}, Group{field1='f1', field2='f2'}={a=[1, 2, 3], b=[4, 5], c=[6]}}

关于java - 使用 Java 8 流的复杂聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43676654/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com