栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

分组和求和对象(如带有Java Lambda的SQL中的对象)?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

分组和求和对象(如带有Java Lambda的SQL中的对象)?

使用

Collectors.groupingBy
是正确的方法,但不要使用单个参数版本来创建每个组的所有项目列表,而应使用两个arg版本,后者使用另一个参数版本Collector来确定如何汇总每个组的元素。

当您要汇总元素的单个属性或仅计算每个组中元素的数量时,这特别平滑:

数数:

list.stream()  .collect(Collectors.groupingBy(foo -> foo.id, Collectors.counting()))  .forEach((id,count)->System.out.println(id+"t"+count));

总结一个属性:

list.stream()  .collect(Collectors.groupingBy(foo -> foo.id,   Collectors.summingInt(foo->foo.targetCost)))  .forEach((id,sumTargetCost)->System.out.println(id+"t"+sumTargetCost));

在您要聚合多个属性的情况下,指定一种自定义归约操作(如此答案中所建议的那样)是正确的方法,但是,您可以在分组操作期间执行归约操作,因此无需将整个数据收集到Map<…,List>执行还原之前的a :

(我假设您

import static java.util.stream.Collectors.*;
现在使用…)

list.stream().collect(groupingBy(foo -> foo.id, collectingAndThen(reducing(  (a,b)-> new Foo(a.id, a.ref, a.targetCost+b.targetCost, a.actualCost+b.actualCost)),      Optional::get)))

.forEach((id,foo)->System.out.println(foo));
为了完整起见,这里是一个超出您问题范围的问题的解决方案:如果要GROUP BY多个列/属性该怎么办?

跳入程序员头脑的第一件事是用来groupingBy提取流元素的属性并创建/返回新的关键对象。但这要求键属性具有适当的holder类(而Java没有通用的Tuple类)。

但是还有另一种选择。通过使用三参数形式,groupingBy我们可以为实际Map实现指定供应商,该供应商将确定键的相等性。通过使用带有比较器比较多个属性的排序映射,我们无需其他类即可获得所需的行为。我们只需要注意不要使用比较器忽略的关键实例中的属性,因为它们只有任意值:

list.stream().collect(groupingBy(Function.identity(),  ()->new TreeMap<>(    // we are effectively grouping by [id, actualCost]    Comparator.<Foo,Integer>comparing(foo->foo.id).thenComparing(foo->foo.actualCost)  ), // and aggregating/ summing targetCost  Collectors.summingInt(foo->foo.targetCost))).forEach((group,targetCostSum) ->    // take the id and actualCost from the group and actualCost from aggregation    System.out.println(group.id+"t"+group.actualCost+"t"+targetCostSum));


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/509411.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号