The use case of stream groupingBy, a new feature of java8, I will teach you how to change 100 lines of code into 1 line

Java8 has been out for many years, and many features have been benefited so far. It is really too powerful.

What I want to talk about today is the use case of stream groupingBy. Friends who like it can learn from it.
If you use the groupingBy method proficiently, you can change at least 20 lines of code into 1 line every time you write code. Some people may say, how is this possible? I tell you, nothing is impossible, today I will tell you how to turn 20 lines of code into 1 line of code

Background: The project needs to implement a function of synchronizing roles from a third party. There are categories on roles, that is, role groups. The interface for obtaining roles and the interface for obtaining role groups are separate. When the synchronized roles and role groups are written to the database , will each produce the id of their own system, and of course also record the relationship of the synchronized data id, so as to ensure that the same piece of data is updated. The relationship between roles and role groups in the system is associated with the id of the system. Therefore, after obtaining the role data from a third party, it is necessary to find the role group in the system according to the role group id to which the third-party role belongs, and then write to the database

Directly roll the code, the initial version:

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

illustrate:

  1. The cateInfo object is a map collection, the key is the id of the third-party role group, and the value is the collection of all roles under the role group
  2. The for loop traverses the role data and classifies it by the role group id. If the key already exists in cateInfo, take out the value and add the role to the list.

First of all, let me explain why you need to classify in this way. The reason is that there may be tens of thousands of roles obtained from third parties. If you don’t classify, you can directly loop through the list of third-party roles, and then search in the local database according to the classification of roles. If you use a role group, you need to query the database tens of thousands of times for the role group, which will consume more performance. If you press the classification semicolon and then loop through the cateInfo map set elements to query, generally there are only a few role groups, that is, you only need to query the database tens of thousands of times, but now you only need to query a few times, and the performance is greatly improved. .

Ok, so far, the above code groups the roles according to the third-party role group id. It seems that there is nothing wrong with the code, and indeed there is nothing wrong with it, but the amount of code is too much

Inadvertently, I remembered the use of the new feature stream groupingBy of java8. Through this feature, with a small amount of code, you can easily classify a collection object by a certain field

So, the above code:

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

The amount of code, one line is enough
This is the convenience brought by the new features of java8, which saves a lot of code for our programmers, and the program is more concise

In fact, Collectors.groupingBy groups the items in the collection according to one or more attributes
1. If multiple attributes are required to be grouped, multiple attributes can be grouped together

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

You can choose grouping requirements according to the grouping situation
2. Find the total

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

3. Sum

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

Wait, there are many ways to use it. Here are some examples. Others need to be used according to actual scenarios.

Guess you like

Origin blog.csdn.net/huangxuanheng/article/details/118993509