小技巧保证分组groupingBy后排序不变

小技巧保证分组groupingBy后排序不变

排查

首先去api中查找解决,查看Java 的 java.util.stream 包 Collectors 类 groupingBy 方法实现,结果如下:

    public static  Collector>>
     groupingBy(Function classifier) {
         return groupingBy(classifier, toList());
     }
  
 //两个参数
     public static 
     Collector> groupingBy(Function classifier,
                                           Collector downstream) {
         return groupingBy(classifier, HashMap::new, downstream);
     }
     
 //三个参数
   public static >
     Collector groupingBy(Function classifier,
                                   Supplier mapFactory,
                                   Collector downstream) {......}

通过java api 发现 groupingBy 调用是内部自己创建了一个 HashMap ( HashMap::new)。因为 hashMap,是无无序的,是根据key的hashcode进行hash,然后放入对应的地方。所以在按照一定顺序put进HashMap中,然后遍历出HashMap的顺序跟put的顺序不同。

知道这个了就明白了为什么无序了。所以我们直接调用三个参数的 groupingBy 方法mapFactory ,传入有顺序的Map, LinkedHashMap 就可以了。

关于 LinkedHashMap 的信息自行百度

解决

创建Person数据集合,然后按照年龄排序,排序后进行分组,保证分组后顺序不变。

    private static List getPersionList() {
           List persons = new ArrayList<>();
           for (int i = 1; i <= 40; i++) {
               Random r = new Random();
               Person person = new Person();
               person.setName("abel-" + i);
               person.setSex((int) (Math.random() * 2));
               person.setGroup(String.valueOf(i%2));
               person.setAge(25 + r.nextInt(50));
               persons.add(person);
           }
           return persons;
    
       }
    
    
       /**
        * 分组
        */
       private static void groupByTest() {
           List persons = getPersionList();
           //将list 排序,并按照排序后的结果进行有序分组
           LinkedHashMap> ageMap = personsSort.stream().sorted(Comparator.comparingInt(Person::getAge)).collect(Collectors.groupingBy(Person::getAge, LinkedHashMap::new, Collectors.toList()));
       }

你可能感兴趣的:(java)