如何使用Collectors.groupingBy来代替分组元素的列表来获取同一组中元素的某些属性的总和



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

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

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

我的目标是得到一张像这样的地图:

Map<Month, Double>

其中Month与旧地图保持不变,但每个月的所有购买价格都会相加并加倍。

有什么办法做到这一点吗?

假设每个Purchase都有getPrice方法为每个特定购买返回double,则在Collectors.groupingBy:中使用Collectors.summingDouble下游收集器

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

您可以使用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,                     // group using month names
Collectors.summingDouble(Purchase::getValue)) // sum price of each purchase in group
//                                 ^^^^^^^^
//      pick method which returns value/price of that purchase 
);

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

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

诚然,它没有迄今为止给出的其他答案那么优雅,因为它需要一行额外的Map来获取结果,但它正在工作,stream正在运行(有点(。

最新更新