How to use Collectors.groupingBy to instead of list of grouped elements get sum of some property of elements in same group?

huangapple go评论75阅读模式
英文:

How to use Collectors.groupingBy to instead of list of grouped elements get sum of some property of elements in same group?

问题

所以基本上我的程序看起来像这样:

Map<Month, List<Purchase>> map2 = purchases
        .stream()
        .collect(Collectors.groupingBy(Purchase::getMonthOfDate));

这创建了一个包含月份和购买列表的Map作为值(每个购买包含一个价格)。

我的目标是获得一个看起来像这样的Map:

Map<Month, Double>

其中月份与旧Map中的相同,但每个月的购买价格都被累加并作为double值放入其中。

有没有办法实现这个目标?

英文:

So basically my program looks like this:

Map&lt;Month, List&lt;Purchase&gt;&gt; map2 = purchases
                .stream()
                .collect(Collectors.groupingBy(Purchase::getMonthOfDate));

which creates Map containing the Month and a list of Purchases as values (each Purchase contains a Price).

My goal is getting a Map that looks like this:

Map&lt;Month, Double&gt;

where Month stays the same as the old map but all prices of the Purchases for each month get summed up and put in as double.

Is there any way to achieve that?

答案1

得分: 4

你可以使用 public static <T, K, A, D> Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream)

在这里,downstream 收集器处理同一组中的元素,Collectors.summingDouble 看起来是你可能想在这里使用的内容。

所以,代替这段代码:

.collect(Collectors.groupingBy(Purchase::getMonthOfDate));

你可以使用类似这样的代码:

.collect(Collectors.groupingBy(
      Purchase::getMonthOfDate,                     // 使用月份名称进行分组
      Collectors.summingDouble(Purchase::getValue)) // 对组中每个购买的价格求和
      //                                 ^^^^^^^^
      //      选择返回购买价格的方法
);
英文:

You could use public static &lt;T,​K,​A,​D&gt; Collector&lt;T,​?,​Map&lt;K,​D&gt;&gt; groupingBy​(Function&lt;? super T,​? extends K&gt; classifier,
Collector&lt;? super T,​A,​D&gt; downstream)
.

Here downstream Collector handles elements in same group and Collectors.summingDouble looks like what you may want to use here.

So instead of

.collect(Collectors.groupingBy(Purchase::getMonthOfDate));

you could use something like

.collect(Collectors.groupingBy(
      Purchase::getMonthOfDate,                     // group using month names
      Collectors.summingDouble(Purchase::getValue)) // sum price of each purchase in group
      //                                 ^^^^^^^^
      //      pick method which returns value/price of that purchase 
);

答案2

得分: 4

假设每个 Purchase 都有一个返回特定购买金额的 getPrice 方法,使用 Collectors.groupingBy 中的 Collectors.summingDouble 下游收集器:

Map<Month, Double> monthlySumOfPurchases = purchases
                .stream()
                .collect(Collectors.groupingBy(
                        Purchase::getMonthOfDate, 
                        Collectors.summingDouble(Purchase::getPrice)));
英文:

Assuming each Purchase has getPrice method returning double for each particular purchase, use the Collectors.summingDouble downstream collector within the Collectors.groupingBy:

Map&lt;Month, Double&gt; monthlySumOfPurchases = purchases
                .stream()
                .collect(Collectors.groupingBy(
                        Purchase::getMonthOfDate, 
                        Collectors.summingDouble(Purchase::getPrice)));

答案3

得分: 2

这里有一个使用 forEach 的替代方案:

Map<Month, Double> monthlyPurchasePriceSums = new HashMap<>();
map2.forEach((key, value) -> 
		monthlyPurchasePriceSums.put(key,
									value.stream()
										.mapToDouble(Purchase::getPrice).sum()
									)
);

诚然,这不像到目前为止给出的其他答案那样优雅,因为它需要额外的一行来创建接收结果的 Map,但它是可行的,并且进行了一点点的流操作。

英文:

Here's an alternative that uses forEach:

Map&lt;Month, Double&gt; monthlyPurchasePriceSums = new HashMap&lt;&gt;();
map2.forEach((key, value) -&gt; 
		monthlyPurchasePriceSums.put(key,
									value.stream()
										.mapToDouble(Purchase::getPrice).sum()
									)
);

Admittedly, it's not as elegant as the other answers given so far because it needs an extra line for the Map that takes the results, but it's working and streaming (a little).

huangapple
  • 本文由 发表于 2020年9月1日 21:37:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63688862.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定