首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >流collectingAndThen获得最新记录以求和一个值

流collectingAndThen获得最新记录以求和一个值
EN

Stack Overflow用户
提问于 2021-01-15 14:32:50
回答 2查看 524关注 0票数 2

目前,我正在面对下面的数据集。我的目标是通过前两列得到最新的Column4组的和。

代码语言:javascript
运行
复制
// 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
...

我试过的是

代码语言:javascript
运行
复制
// 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.groupingByCollectors.maxByCollectors.summingInt

但这总是错误的。

我的理想地图应该如下所示:

1->bbb->3481->xxx->1112->xxx->1

如果有任何补充剂想要的话,请帮助我。谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-01-15 15:16:50

你可以通过:

代码语言:javascript
运行
复制
    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对分组进行column3,因为我们希望对其进行后处理。

根据column3进行分组,我们希望按版本获得最大值,我们使用另一个collectingAndThen,因为maxBy创建和Optional,所以我们应用Optional::Get来获得Map<String, Foo>而不是Map<String, Optional<Foo>>

post过程是对地图中Foo的所有column4进行求和,这些都是带有最大版本的。

票数 2
EN

Stack Overflow用户

发布于 2021-01-15 17:24:11

将简化模型表示为:

代码语言:javascript
运行
复制
record Foo(Long one, String two, String three, int value, int version) {
}

record Result(Long one, String two, int totalValue) {
}

您可以从按前三个属性分组开始,并将值映射到一个标识,选择最大版本。

代码语言:javascript
运行
复制
Map<List<Object>, Foo> groupedMaxVersion = fooList.stream()
        .collect(Collectors.toMap(foo -> Arrays.asList(foo.one(), foo.two(), foo.three()),
                foo -> foo, BinaryOperator.maxBy(Comparator.comparing(Foo::version))));

接下来可以根据第4列中的值对下游进行求和:

代码语言:javascript
运行
复制
Map<List<Object>, Integer> resultMapping = groupedMaxVersion.entrySet().stream()
        .collect(Collectors.groupingBy(e -> Arrays.asList(e.getKey().get(0), e.getKey().get(1)),
                Collectors.summingInt(e -> e.getValue().value())));

此外,您只需要将其按需要的结果数据结构进行框架设置即可。

代码语言:javascript
运行
复制
resultMapping.entrySet().stream()
                .map(e -> new Result((Long) e.getKey().get(0), (String) e.getKey().get(1), e.getValue()))
                .collect(Collectors.toList()); 
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65737983

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档