• java8 : Collectors.groupingBy(分组)


    Collectors.groupingBy配合Stream流使用,可以对集合中一个或多个属性进行分组,分组后还可以做聚合运算。

    首先把数据放入集合:

    	Product prod1 = new Product(1L, 1, new BigDecimal("15.5"), "面包", "零食");
        Product prod2 = new Product(2L, 2, new BigDecimal("20"), "饼干", "零食");
        Product prod3 = new Product(3L, 3, new BigDecimal("30"), "月饼", "零食");
        Product prod4 = new Product(4L, 3, new BigDecimal("10"), "青岛啤酒", "啤酒");
        Product prod5 = new Product(5L, 10, new BigDecimal("15"), "百威啤酒", "啤酒");
        Product prod6 = new Product(5L, 7, new BigDecimal("25"), "百威啤酒", "啤酒");
    
        List<Product> prodList = List.of(prod1, prod2, prod3, prod4, prod5, prod6);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    按照类别分组

    Map<String, List<Product>> map1 = prodList.stream().collect(Collectors.groupingBy(Product::getCategory));
    Set<Map.Entry<String, List<Product>>> entries1 = map1.entrySet();
    for (Map.Entry<String, List<Product>> entry : entries1) {
        System.out.println(entry);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    输出结果:

    啤酒=[Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒'}, Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒'}, Product{id=5, num=7, price=25, name='百威啤酒', category='啤酒'}]
        
    零食=[Product{id=1, num=1, price=15.5, name='面包', category='零食'}, Product{id=2, num=2, price=20, name='饼干', category='零食'}, Product{id=3, num=3, price=30, name='月饼', category='零食'}]
    
    • 1
    • 2
    • 3

    按照多个属性拼接分组

    Map<String, List<Product>> map2 = prodList.stream()
            .collect(Collectors.groupingBy(item -> item.getCategory() + "_" + item.getName()));
    Set<Map.Entry<String, List<Product>>> entries2 = map2.entrySet();
    for (Map.Entry<String, List<Product>> entry : entries2) {
        System.out.println(entry);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出结果(可以看到百威啤酒那组有两个对象):

    零食_月饼=[Product{id=3, num=3, price=30, name='月饼', category='零食'}]
        
    零食_面包=[Product{id=1, num=1, price=15.5, name='面包', category='零食'}]
        
    啤酒_百威啤酒=[Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒'}, Product{id=5, num=7, price=25, name='百威啤酒', category='啤酒'}]
        
    啤酒_青岛啤酒=[Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒'}]
        
    零食_饼干=[Product{id=2, num=2, price=20, name='饼干', category='零食'}]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    根据不同条件分组

    这里按照num数值的大小来分

    Map<String, List<Product>> map3 = prodList.stream().collect(Collectors.groupingBy(item -> {
        if (item.getNum() > 3) {
            return "num大于3";
        } else if (item.getNum() < 3) {
            return "num小于3";
        } else {
            return "num等于3";
        }
    }));
    Set<Map.Entry<String, List<Product>>> entries3 = map3.entrySet();
    for (Map.Entry<String, List<Product>> entry : entries3) {
        System.out.println(entry);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    输出结果:

    num小于3=[Product{id=1, num=1, price=15.5, name='面包', category='零食'}, Product{id=2, num=2, price=20, name='饼干', category='零食'}]
        
    num等于3=[Product{id=3, num=3, price=30, name='月饼', category='零食'}, Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒'}]
        
    num大于3=[Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒'}, Product{id=5, num=7, price=25, name='百威啤酒', category='啤酒'}]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    map实体示例:

    List<Map> deviceList = ToLowerCaseForList(iBoardDataDao.queryDeviceProduce(params));
           Map<String, List<Map>> deviceMap = deviceList.stream().collect(Collectors.groupingBy(map->{
               Map result = map;
                if("".equals(String.valueOf(result.get("usestate")))){
                    return "osNoOrder";
                }else{
                    return String.valueOf(result.get("usestate"));
                }
           }));
          // Map> deviceMap = deviceList.stream().collect(Collectors.groupingBy(map-> map.get("usestate"));
           Map<String,Object> resultMap = new HashMap<>();
           deviceMap.forEach((key,list)->{
              resultMap.put(key,list.size());
           });
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    多级分组

    这里先按照类别分组,再按照num分组

    Map<String, Map<String, List<Product>>> map4 = prodList.stream()
            .collect(Collectors.groupingBy(Product::getCategory, Collectors.groupingBy(item -> {
                if (item.getNum() >= 8) {
                    return "num大于等于8";
                } else {
                    return "num小于8";
                }
            })));
    Set<Map.Entry<String, Map<String, List<Product>>>> entries4 = map4.entrySet();
    for (Map.Entry<String, Map<String, List<Product>>> entry : entries4) {
        System.out.println(entry);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    输出结果:

    啤酒={num小于8=[Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒'}, Product{id=5, num=7, price=25, name='百威啤酒', category='啤酒'}], num大于等于8=[Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒'}]}
    
    零食={num小于8=[Product{id=1, num=1, price=15.5, name='面包', category='零食'}, Product{id=2, num=2, price=20, name='饼干', category='零食'}, Product{id=3, num=3, price=30, name='月饼', category='零食'}]}
    
    • 1
    • 2
    • 3

    分组后再聚合求总数

    这里先按照类别分组,再聚合求总数

    Map<String, Long> map5 = prodList.stream()
            .collect(Collectors.groupingBy(Product::getCategory, Collectors.counting()));
    Set<String> strings5 = map5.keySet();
    for (String s : strings5) {
        System.out.println(s + "---" + "总数:" + map5.get(s));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出结果:

    啤酒---总数:3
    零食---总数:3
    
    • 1
    • 2

    分组后再做相加运算

    这里先按照类别分组,再聚合运算(把num相加)

    Map<String, Integer> map6 = prodList.stream()
            .collect(Collectors.groupingBy(Product::getCategory, Collectors.summingInt(Product::getNum)));
    Set<String> strings6 = map6.keySet();
    for (String s : strings6) {
        System.out.println(s + "---" + "num相加后:" + map6.get(s));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出结果:

    啤酒---num相加后:20
    零食---num相加后:6
    
    • 1
    • 2
  • 相关阅读:
    tomcat高并发下优化详解及连接数和线程池
    有没有可以大量注册虾皮买家号的软件
    群晖(Synology)NAS 安装 MongoDB
    递归的本质
    Apache HBase MTTR 优化实践
    分布式电源接入对配电网影响分析(Matlab代码实现)
    Spring的开幕式——Spring概述与设计思想
    ubuntu 20.04安装RTL8821CE无线网卡驱动
    ref的使用
    约数——正约数个数求法及其原理,求N的正约数集合
  • 原文地址:https://blog.csdn.net/strggle_bin/article/details/134382644