目前,我面临以下数据集。我的目标是通过前两列获取 Column4 组的最新总和。
// Column5 = version
new Foo(1, "bbb", "cccc", 111, 0)
new Foo(1, "bbb", "cccc", 234, 1) // latest
new Foo(1, "bbb", "dddd", 111, 0)
new Foo(1, "bbb", "dddd", 112, 1)
new Foo(1, "bbb", "dddd", 113, 2)
new Foo(1, "bbb", "dddd", 114, 3) // latest
new Foo(1, "xxx", "cccc", 111, 0) // latest
new Foo(2, "xxx", "yyyy", 0, 0)
new Foo(2, "xxx", "yyyy", 1, 1) // latest
...
我尝试过的是
// key: Column1, key: Column2, value: latest sum of Column4
Map<Long, Map<String, Integer>> fooMap = fooList.stream().collect(
Collectors.groupingBy(Foo::getColumn1, Collectors.groupingBy(Foo::getColumn2,
Collectors.collectingAndThen(????))));
是否????
我尝试过的部分Collectors.groupingBy
, Collectors.maxBy
, Collectors.summingInt
但它总是错误的。 ??
我理想的 map 应该如下所示:
1->bbb->348
, 1->xxx->111
, 2->xxx->1
.
请帮忙😵 如果需要任何补充品请告诉我。谢谢。
最佳答案
您可以通过以下方式获取它:
Map<Long, Map<String, Integer>> fooMap = fooList.stream().collect(
groupingBy(Foo::getColumn1,
groupingBy(Foo::getColumn2,
collectingAndThen(
groupingBy(Foo::getColumn3,
collectingAndThen(
maxBy(comparing(Foo::getVersion)),
Optional::get
)),
m -> m.values().stream().mapToInt(Foo::getColumn4).sum()
)
)
));
首先按column1和column2分组,然后我们使用collectingAndThen
按第 3 列分组,因为我们要对其进行后处理。
按第3列分组,我们想要按版本获取最大值,我们使用另一个 collectingAndThen
,因为 maxBy 创建了和 Optional
,所以我们应用 Optional::Get
获得 Map<String, Foo>
而不是Map<String, Optional<Foo>>
.
后期处理是将 map 中 Foo 的所有第 4 列求和,即具有最大版本的列。
关于java - 流收集然后获取最新记录求和一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65737983/