【Java8】 Collectors工具类实现分组统计

分组、求和、求平均、求最大值、求最小值的统计在开发中经常会碰到。

之前在使用Mybatis的时候会直接用到聚合函数进行统计查询。但是代码中这样写会有一定的局限性,比如:MySQL的聚合函数在程序切换数据库 时聚合函数会失效。  亦或者是在微服务框架下,调用别人写的接口时对方并未提供统计方法,所以分享一下通过Java8的Collectors类来实现分组的方式。其他聚合函数类似。

1、根据单字段分组,返回各类别总数。

Map<String,Long> consInfoGroupMap =
                consInfoVos.stream().collect(Collectors.groupingBy(ConsInfoVo::getSourceTypeName,Collectors.counting()));

Collectors.counting()表示直接分组返回count,其中,Map<String,Long>中的String即为分组的字段,例如按照type分类,则这里的string就是具体的某一个type类型,如:已处理,未处理等。后面的Long即为每种类别的数量。需要组装数据或者获取数据时遍历这个map即可。

 

2、根据单字段分组,返回各类的对象集合。

Map<Object, List<ConsInfoVo>> consInfoCollect =
                    consInfoVoList.stream().collect(
                            Collectors.groupingBy(ConsInfoVo -> ConsInfoVo.getStatus()));

执行该行代码,返回值为Map<String,List<ConsInfoVo>,很直观的看出,返回的为某一个分组的对象集合。同理,String为分组的字段,List<> 为分组后的对象集合。遍历map即可操作集合。

 

3、根据单字段分组,返回类型为对象。【分组字段为时间,既按照时间按天分组】

Map<Object, List<ConsInfoVo>> consInfoCollect =
                    consInfoVoList.stream().collect(
                            Collectors.groupingBy(ConsInfoVo -> (ConsInfoVo.getCreateTime()).toLocalDate()));


//解析时注意类型转换,因为分组前将CreateTime转换为了LocalDate,
String groupDate = LocalDateUtil.localDateToStr((LocalDate) object);

数据库creatTime字段为LocalDateTime,所以分组前转换为LocalDate再去分组。

 

4、根据两个字段分组,返回结果为对象集合。

Map<String, Map<String, List<ConsMediaVo>>> consMediaCollect =
                    consMediaVoList.stream().collect(
                            Collectors.groupingBy(
                                    ConsMediaVo::getFileType, Collectors.groupingBy(ConsMediaVo -> ConsMediaVo.getStatus())));

以上代码首先按照fileType分组,然后按照status分组。返回值Map<String, Map<String, List<OrderDealVo>>>,与上面的返回值雷同,无非是多了一层嵌套。最外层Map的key为第一个分组字段的值,内部的Map的key为第二个分组字段的值,之后便是解析list的过程。

分组后的结果集均为Map,其中Map中的key的数据类型取决于分组字段的数据类型,当分组字段的类型改变,则Map的key的数据类型为Object,转换时为改变后的数据类型,不然会报数据类型转化异常。具体见如下例子:

 

5、根据两个字段分组,返回结果为对象集合。【其中一个分组字段为时间,并且按天分组】

Map<String, Map<Object, List<ConsMediaVo>>> consMediaCollect =
                    consMediaVoList.stream().collect(
                            Collectors.groupingBy(
                                    ConsMediaVo::getFileType, Collectors.groupingBy(ConsMediaVo -> (ConsMediaVo.getCreateTime()).toLocalDate())));


//解析时注意类型转换,因为分组前将CreateTime转换为了LocalDate,
String groupDate = LocalDateUtil.localDateToStr((LocalDate) object);

以上代码先按照fileType分类,然后按照创建时间分类。创建时间createTime在数据库中存储的是LocalDateTime类型,如果直接分组肯定是每天一条数据,所以需要将LocalDateTime转换为LocalDate去分组。这个时侯 数据类型变动了,所以 返回的为Object类型的key值。其余操作与之前类似。

可根据具体需求采取相应的方式,建议优先数据库分组,因为解析结果集是一个距大的工作量。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值