JDK8:Lambda根据 单个字段、多个字段,分组求和及次数

931 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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())));
                                
    }
}