【Java8】 Collectors工具类实现分组统计
分组、求和、求平均、求最大值、求最小值的统计在开发中经常会碰到。之前在使用Mybatis的时候会直接用到聚合函数进行统计查询。但是代码中这样写会有一定的局限性,比如:MySQL的聚合函数在程序切换数据库 时聚合函数会失效。 亦或者是在微服务框架下,调用别人写的接口时对方并未提供统计方法,所以分享一下通过Java8的Collectors类来实现分组的方式。其他聚合函数类似。1、根据单字段分...
分组、求和、求平均、求最大值、求最小值的统计在开发中经常会碰到。
之前在使用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值。其余操作与之前类似。
可根据具体需求采取相应的方式,建议优先数据库分组,因为解析结果集是一个距大的工作量。
更多推荐
所有评论(0)