java分组还是sql分组_使用Java lambdas对SQL进行分组和总和对象?

使用Collectors.groupingBy是正确的方法,而不是使用单个参数版本,它将为每个组创建一个所有项目的列表,您应该使用

the two arg version,它需要另一个收集器来确定如何聚合每个组的元素.

当您要聚合元素的单个属性或仅计算每个元素的数量时,这一点尤其顺利:

>计数:

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));

在您想要聚合多个属性指定自定义缩减操作的情况下,like suggested in this answer是正确的方法,但是您可以在分组操作期间执行缩减权限,因此无需将整个数据收集到Map< ... ,列表>执行裁减前:

(我假设你使用import static java.util.stream.Collectors.*; now …)

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来提取流元素的属性并创建/返回一个新的关键对象.但是这需要关键属性的适当的持有者类(而Java没有通用的Tuple类).

但还有一个选择.通过使用three-arg form of groupingBy,我们可以为实际的Map实现指定一个供应商,这将确定关键的平等.通过使用具有比较多个属性的比较器的排序映射,我们获得所需的行为,而不需要额外的类.我们只需要注意不要使用比较器忽略的关键实例的属性,因为它们只有任意的值:

list.stream().collect(groupingBy(Function.identity(),

()->new TreeMap<>(

// we are effectively grouping by [id, actualCost]

Comparator.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));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值