持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情
最近遇到一个需求,从redis里面拿到数据,需要对数据进行一系列操作,比如根据某个字段分组,然后统计各个分组的人数;根据多个字段分组,统计每个分组及子分组的人数;分组后获取每组的聚合数值;内存里面操作lamda表达式提供了很好的支撑。
情景:最近油价暴涨,我们需要分别统计用车公司92、93、98号汽油的使用次数和使用量。
1、根据 单个字段,分组求和:根据92号汽油这个字段,计算一个list集合里,同属于92号汽油的某个字段累加和;
2、根据 多个字段,分组求和:
(1)先根据92号汽油这个字段,再根据1这个字段,计算一个list集合里,同属于92号汽油和1的某个字段累加和;
(2)先根据92号汽油这个字段,再根据2这个字段,计算一个list集合里,同属于92号汽油和2的某个字段累加和;
代码如下:
public class StreamCodeGroupBy {
@Data
static class DataStatisticsResultMiddle{
private String datas;//油标号
private String carrierid;//加油人ID
private Long enusers;//加油量
}
public static void main(String[] args) {
List<DataStatisticsResultMiddle> li = new ArrayList<>();
DataStatisticsResultMiddle middle1 = new DataStatisticsResultMiddle();
middle1.setDatas("92");
middle1.setCarrierid("1");
middle1.setEnusers(100L);
DataStatisticsResultMiddle middle2 = new DataStatisticsResultMiddle();
middle2.setDatas("92");
middle2.setCarrierid("1");
middle2.setEnusers(150L);
DataStatisticsResultMiddle middle3 = new DataStatisticsResultMiddle();
middle3.setDatas("92");
middle3.setCarrierid("2");
middle3.setEnusers(200L);
DataStatisticsResultMiddle middle4 = new DataStatisticsResultMiddle();
middle4.setDatas("93");
middle4.setCarrierid("1");
middle4.setEnusers(400L);
DataStatisticsResultMiddle middle5 = new DataStatisticsResultMiddle();
middle5.setDatas("93");
middle5.setCarrierid("2");
middle5.setEnusers(500L);
DataStatisticsResultMiddle middle6 = new DataStatisticsResultMiddle();
middle6.setDatas("98");
middle6.setCarrierid("2");
middle6.setEnusers(500L);
DataStatisticsResultMiddle middle7 = new DataStatisticsResultMiddle();
middle7.setDatas("98");
middle7.setCarrierid("2");
middle7.setEnusers(200L);
DataStatisticsResultMiddle middle8 = new DataStatisticsResultMiddle();
middle8.setDatas("98");
middle8.setCarrierid("1");
middle8.setEnusers(700L);
li.add(middle1);
li.add(middle2);
li.add(middle3);
li.add(middle4);
li.add(middle5);
li.add(middle6);
li.add(middle7);
li.add(middle8);
//单个字段,分组求和(datas)
Map<String, LongSummaryStatistics> enusersCollect1 =
li.stream().collect(Collectors.groupingBy(DataStatisticsResultMiddle:: getDatas, Collectors.summarizingLong(DataStatisticsResultMiddle :: getEnusers)));
LongSummaryStatistics you92 = enusersCollect1.get("92");
LongSummaryStatistics you93 = enusersCollect1.get("93");
LongSummaryStatistics you98 = enusersCollect1.get("98");
System.out.println("油92="+you92.getSum()+"L =====油93="+you93.getSum()+"L=======油98="+you98.getSum());
System.out.println("油92="+you92.getCount()+"L =====油93="+you93.getCount()+"L=======油98="+you98.getCount());
System.out.println("分割线***********************************");
//多个字段,分组求和(先按datas分组,再按Carrierid分组,求和)
Map<String, Map<String, LongSummaryStatistics>> enusersCollect2 =
li.stream().collect(Collectors.groupingBy(DataStatisticsResultMiddle:: getDatas,
Collectors.groupingBy(DataStatisticsResultMiddle:: getCarrierid,
Collectors.summarizingLong(DataStatisticsResultMiddle :: getEnusers))));
Map<String, LongSummaryStatistics> map92 = enusersCollect2.get("92");
Map<String, LongSummaryStatistics> map93 = enusersCollect2.get("93");
Map<String, LongSummaryStatistics> map98 = enusersCollect2.get("98");
for(Map.Entry<String, LongSummaryStatistics> entry : map92.entrySet()){
System.out.println(entry.getKey());
System.out.println(entry.getValue().getSum());
}
for(Map.Entry<String, LongSummaryStatistics> entry : map93.entrySet()){
System.out.println(entry.getKey());
System.out.println(entry.getValue().getSum());
}
for(Map.Entry<String, LongSummaryStatistics> entry : map98.entrySet()){
System.out.println(entry.getKey());
System.out.println(entry.getValue().getSum());
}
//多个字段,分组求和(先按datas分组,再按Carrierid分组,求次数)
Map<String, Map<String, Long>> enusersCollect2 =
li.stream().collect(Collectors.groupingBy(DataStatisticsResultMiddle:: getDatas,
Collectors.groupingBy(DataStatisticsResultMiddle:: getCarrierid,
Collectors.counting())));
}
}