Java 8 Streaming:使用聚合进行分组

use*_*736 6 java group-by aggregation java-stream

我在使用Stream API找到一个好的方法/实现时遇到以下困难:

我有一个元素列表,每个元素由一个字符串和一个整数组成.现在我喜欢按字符串值对元素进行分组,然后对于每个组,我希望得到与该组相关的元素的整数值之和.

示例:我有以下3个要素:

("GroupA", 100) ("GroupA", 50) ("GroupB", 10)
Run Code Online (Sandbox Code Playgroud)

因此,我希望得到一个由以下两个(键,值)对组成的映射:

("GroupA, 150) ("GroupB, 10)
Run Code Online (Sandbox Code Playgroud)

我不知道如何解决这个问题.到目前为止我想出的最有希望的是:

elements.stream().collect(Collectors.groupingBy(e-> e.getGroup()))
            .merge(group, elementsOfTheGroup, (...));
Run Code Online (Sandbox Code Playgroud)

但我不确定要插入哪个函数作为merge方法的最后一个参数.但我不知道我是否应该使用合并方法.

对此最优雅的实现是什么?

Tun*_*aki 9

您需要添加下游收集器Collectors.groupingBy(classifier, downstream).此收集器收集分类为相同密钥的所有元素.在这种情况下,我们只需要将所有数字加在一起使用Collectors.summingInt(mapper),mapper是一个函数,将数字返回到sum.

假设可以使用getter检索此数字getNumber(),您可以:

Map<String, Integer> result =
    elements.stream().collect(Collectors.groupingBy(
        e -> e.getGroup(),
        Collectors.summingInt(e -> e.getNumber())
    ));
Run Code Online (Sandbox Code Playgroud)

您可以使用方法引用而不是上面的两个lambdas.Element例如,如果元素的类是,那么你将拥有

Map<String, Integer> result =
    elements.stream().collect(Collectors.groupingBy(
        Element::getGroup,
        Collectors.summingInt(Element::getNumber)
    ));
Run Code Online (Sandbox Code Playgroud)