英文:
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<Month, List<Purchase>> 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<Month, Double>
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
在这里,downstream
收集器处理同一组中的元素,Collectors.summingDouble
看起来是你可能想在这里使用的内容。
所以,代替这段代码:
.collect(Collectors.groupingBy(Purchase::getMonthOfDate));
你可以使用类似这样的代码:
.collect(Collectors.groupingBy(
Purchase::getMonthOfDate, // 使用月份名称进行分组
Collectors.summingDouble(Purchase::getValue)) // 对组中每个购买的价格求和
// ^^^^^^^^
// 选择返回购买价格的方法
);
英文:
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<Month, Double> 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<Month, Double> monthlyPurchasePriceSums = new HashMap<>();
map2.forEach((key, value) ->
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 stream
ing (a little).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论