java8新特性之stream groupingBy 使用案例,哥教你如何100行代码变为1行搞定

java8出来了好多年,好多特性一直收益至今,真的太强大了

我今天要说的是stream groupingBy 使用案例,喜欢的朋友可以借鉴
如果熟练使用了groupingBy 方式,每次写代码,至少可以将20行代码变为1行,也许有人说,这怎么可能?我告诉你,没有什么不可能的,今天我就告诉你如何将20行的代码,变为1行代码

背景:项目中需要做一个从第三方同步角色的功能,角色上有分类,也就是角色组,获取角色的接口和获取角色组的接口是分开的,同步过来的角色和角色组写到数据库时,都会各自生产自身系统的id,当然也会记录同步过来的数据id的关系,这样才能保证是同一条数据的更新。系统中的角色和角色组的关系,是用系统的id做的关联,因此,从第三方获取到角色数据后,需要根据第三方角色所属角色组id,找到系统中的角色组,再写入到数据库

直接撸代码,初始版本:

Map<String,List<RoleConfInfoVO>>cateInfos=new HashMap<>();

        for (RoleConfInfoVO roleConfInfoVO:roleConfInfoVOS){
    
    
            if(StringUtils.isNotEmpty(roleConfInfoVO.getRoleConfCateId())){
    
    
                if(cateInfos.containsKey(roleConfInfoVO.getRoleConfCateId())){
    
    
                    List<RoleConfInfoVO> infoVOList = cateInfos.get(roleConfInfoVO.getRoleConfCateId());
                    infoVOList.add(roleConfInfoVO);
                }else {
    
    
                    List<RoleConfInfoVO>infoVOList=Lists.newArrayList();
                    infoVOList.add(roleConfInfoVO);
                    cateInfos.put(roleConfInfoVO.getRoleConfCateId(),infoVOList);
                }
            }else {
    
    
                //默认分组
                if(cateInfos.containsKey(defaultGroupSourceId)){
    
    
                    List<RoleConfInfoVO> infoVOList = cateInfos.get(defaultGroupSourceId);
                    infoVOList.add(roleConfInfoVO);
                }else {
    
    
                    List<RoleConfInfoVO>infoVOList=Lists.newArrayList();
                    infoVOList.add(roleConfInfoVO);
                    cateInfos.put(defaultGroupSourceId,infoVOList);
                }
            }
        }

说明:

  1. cateInfo 对象是一个map集合,key是第三方角色组id,value是角色组下的所有角色集合
  2. for循环遍历角色数据,将其按角色组id进行分类,如果已经cateInfo 中已经存在了key,则取出value,将角色添加到list里面

首先说明下,为什么要这样循环去分类,原因是这样,从第三方获取到的角色可能有几万个,如果不进行分类,直接循环遍历第三方角色列表,再根据角色的分类去本地数据库查找角色组,那就要查询角色组几万次数据库,会比较耗性能。如果按分类分号后,再循环遍历cateInfo map集合元素去查询,一般只有几个角色组,也就是原本只需要查询几万次数据库的,现在只需要查询几次就可以了,性能大大提升了。

好了,到这里,上述代码对角色按第三方角色组id的方式分组了,看似代码没啥问题,确实也没啥问题,只是代码量多了

不经意间我想起来了java8的新特性stream groupingBy 的使用,可以通过这个特性,用很少的代码量,就可以轻松的将一个集合对象按某个字段进行分类

于是,上代码:

       Map<String, List<RoleConfInfoVO>> cateInfos = roleConfInfoVOS.stream().collect(Collectors.groupingBy(g -> StringUtils.isEmpty(g.getRoleConfCateId())?defaultGroupSourceId:g.getRoleConfCateId()));

代码量,一行足以
这就是java8新特性带来的便利,为我们程序猿节省了不少代码,程序也更加简洁

事实上,Collectors.groupingBy根据一个或多个属性对集合中的项目进行分组
1.如果需要多个属性进行分组,可以将多个属性拼接分组

Map<String, List<Product>> prodMap = prodList.stream().collect(Collectors.groupingBy(item -> item.getCategory() + "_" + item.getName()));

大家可以根据分组情况自行选择分组需求
2.求总数

Map<String, Long> prodMap = prodList.stream().collect(Collectors.groupingBy(Product::getCategory, Collectors.counting()));

3.求和

Map<String, Integer> prodMap = prodList.stream().collect(Collectors.groupingBy(Product::getCategory, Collectors.summingInt(Product::getNum)));

等等,使用方式有很多,在这里举例这几种,其他需要根据实际场景去使用了

猜你喜欢

转载自blog.csdn.net/huangxuanheng/article/details/118993509
今日推荐