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);

按照类别分组

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);
}

输出结果:

啤酒=[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='零食'}]

按照多个属性拼接分组

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);
}

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

零食_月饼=[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='零食'}]

根据不同条件分组

这里按照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);
}

输出结果:

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='啤酒'}]

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<String, List<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());
       });

多级分组

这里先按照类别分组,再按照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);
}

输出结果:

啤酒={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='零食'}]}

分组后再聚合求总数

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

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));
}

输出结果:

啤酒---总数:3
零食---总数:3

分组后再做相加运算

这里先按照类别分组,再聚合运算(把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));
}

输出结果:

啤酒---num相加后:20
零食---num相加后:6
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java8中,我们可以使用Stream API来对集合进行分组、排序等操作,其中Collectors.groupingBy是一个非常有用的方法。它接收一个Function作为参数,用于将元素映射为分组的键,返回一个Map类型的结果,其中键是由Function映射的结果,值是对应的元素列表。 例如,我们有一个Person类,其中包含姓名和年龄两个属性,我们想按照年龄进行分组: ``` List<Person> persons = Arrays.asList( new Person("John", 30), new Person("Jane", 25), new Person("Bob", 40), new Person("Mary", 35) ); Map<Integer, List<Person>> personsByAge = persons.stream() .collect(Collectors.groupingBy(Person::getAge)); personsByAge.forEach((age, list) -> System.out.println(age + " -> " + list)); ``` 输出结果为: ``` 25 -> [Person{name='Jane', age=25}] 30 -> [Person{name='John', age=30}] 35 -> [Person{name='Mary', age=35}] 40 -> [Person{name='Bob', age=40}] ``` 我们还可以对分组结果进行排序,例如按照年龄从小到大排序: ``` Map<Integer, List<Person>> personsByAgeSorted = persons.stream() .collect(Collectors.groupingBy(Person::getAge, TreeMap::new, Collectors.toList())); personsByAgeSorted.forEach((age, list) -> System.out.println(age + " -> " + list)); ``` 输出结果为: ``` 25 -> [Person{name='Jane', age=25}] 30 -> [Person{name='John', age=30}] 35 -> [Person{name='Mary', age=35}] 40 -> [Person{name='Bob', age=40}] ``` 在这个例子中,我们使用TreeMap作为分组结果的容器,实现了按照年龄从小到大排序的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

strggle_bin

一毛不嫌少,十元不嫌多

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值