精华内容
下载资源
问答
  • Java8 stream 之groupingBy() 分组排序

    万次阅读 热门讨论 2017-12-29 12:06:37
    List matchsList = new ArrayList();... MatchsListMap = matchsList.stream() .collect(Collectors.groupingBy(Matchs::getMatchDate)); 此时MatchsListMap的排序规则是根据MatchDate降序的(默认),也就是说ma
    	List<Matchs> matchsList = new ArrayList();
    	
    	Map<String,List<Matchs>> MatchsListMap=matchsList.stream()
    	.collect(Collectors.groupingBy(Matchs::getMatchDate));	
    

    此时MatchsListMap的排序规则是根据Hash值排序一般来讲认为是无序即可,那么如果需要根据MatchDate升/降序该怎么办呢?

    答案是:

    
    TreeMap<String, List<Matchs>> matchsListMap = matchsList.stream()
    .collect(Collectors.groupingBy(Matchs::getMatchDate,TreeMap::new,Collectors.toList()));
    
    

    此时返回的为TreeMap类型数据,TreeMap默认为按照key升序,matchsListMap.descendingMap()可以降序输出

    2021年1月4日 19:53:19
    补充另一种修改比较器的写法

    List<Integer> resultList = IntStream.rangeClosed(1, 24).map(operand -> 0).boxed().collect(Collectors.toList());
            resultList.set(1,9);
            resultList.set(3,3);
            resultList.set(7,22);
            TreeMap<Integer, List<Integer>> collect = resultList.stream()
                    .collect(Collectors.groupingBy(Function.identity(), () -> {
                        Comparator<Integer> comparing = Comparator.comparing(Function.identity());
                        return new TreeMap<>(comparing.reversed());
                    }, Collectors.toList()));
    
    展开全文
  • JAVA stream groupingBy 分组、排序groupingBy结果key排序 groupingBy得到的结果一般为Map<String, List>形式,之前碰到有人问对得到的Map<String, List>需要对key自然排序groupingBy结果key排序 @...

    JAVA stream groupingBy 分组、排序

    groupingBy得到的结果一般为Map<String, List>形式,之前碰到有人问对得到的Map<String, List>需要对key自然排序

    对groupingBy结果key排序

    @Data
    @AllArgsConstructor
    public class Product {
    
        private String name;
    
        private int count;
        
    }
    
    public static void main(String[] args) {
             Product product = new Product("h", 2);
            Product product1 = new Product("a", 4);
            Product product2 = new Product("a", 2);
            Product product3 = new Product("c", 4);
            Product product4 = new Product("u", 5);
            Product product5 = new Product("u", 2);
            List<Product> list = asList(product, product1, product2, product3, product4, product5);
            TreeMap collects = list.stream().collect(Collectors.groupingBy(Product::getName, TreeMap::new, Collectors.toList()));
        }
    

    其实就是用利用TreeMap的排序特性可以使得key是按自然排序

    展开全文
  • java8 小技巧保证分组groupingBy排序不变

    千次阅读 多人点赞 2020-03-03 14:45:59
    问题: 遇到一个小问题,查询出来一组数据后,按照其中的属性进行groupBy 分组 ,分组后要保证顺序不变。 排查 首先去api中查找解决 //一个参数 public static <... groupingBy(Function<? super T, ? ex...

    问题:

    遇到一个小问题,查询出来一组数据后,按照其中的属性进行groupBy 分组 ,分组后要保证顺序不变。但是实际用groupBy进行分组后,返回的数据是杂乱无章的,没有按照原来list 的顺序返回

    排查

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

    //一个参数
       public static <T, K> Collector<T, ?, Map<K, List<T>>>
        groupingBy(Function<? super T, ? extends K> classifier) {
            return groupingBy(classifier, toList());
        }
    
    //两个参数
        public static <T, K, A, D>
        Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
                                              Collector<? super T, A, D> downstream) {
            return groupingBy(classifier, HashMap::new, downstream);
        }
        
    //三个参数
      public static <T, K, D, A, M extends Map<K, D>>
        Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,
                                      Supplier<M> mapFactory,
                                      Collector<? super T, A, D> downstream) {......}
    

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

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

    关于 LinkedHashMap 的信息自行百度

    解决

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

    //创建数据
     private static List<Person> getPersionList() {
            List<Person> 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<Person> persons = getPersionList();
            //将list 排序,并按照排序后的结果进行有序分组
            LinkedHashMap<Integer, List<Person>> ageMap = personsSort.stream().sorted(Comparator.comparingInt(Person::getAge)).collect(Collectors.groupingBy(Person::getAge, LinkedHashMap::new, Collectors.toList()));
        }
    

    关于 排序Comparator.comparingInt 参考:
    https://www.jianshu.com/p/3f621e51f3

    展开全文
  • 在工作中遇到了java8 stream groupBy 分组排序失效的问题 在此记录一下解决方案 预期效果: 按照年纪倒序并分组 实际结果:返回的数据是杂乱无章,并没有按照年纪倒序 示例代码如下: import java.util.Comparator;...

    在工作中遇到了java8 stream groupBy 分组排序失效的问题

    在此记录一下解决方案

    预期效果: 按照年纪倒序并分组
    实际结果:返回的数据是杂乱无章,并没有按照年纪倒序

    示例代码如下:

    import java.util.Comparator;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    /**
     * @author miao
     */
    public class GroupBySort {
    
        public static void main(String[] args) {
            //构造数据
            List<Student> students = Stream.of(
                    new Student("a", 15),
                    new Student("b", 13),
                    new Student("c", 11),
                    new Student("d", 18),
                    new Student("e", 20)
            ).collect(Collectors.toList());
    
            //按照年纪倒序并分组
            Map<Integer, List<Student>> studentMap = students.stream()
                    .sorted(Comparator.comparing(Student::getAge).reversed())
                    .collect(Collectors.groupingBy(Student::getAge));
    
            System.out.println(studentMap);
        }
    }
    
    class Student {
    
        private String name;
    
        private Integer age;
    
        public Student(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    

    在这里插入图片描述

    排查原因

    查看java.util.stream.Collectors类的groupingBy方法,源码如下
    //一个入参
    public static <T, K> Collector<T, ?, Map<K, List<T>>>
        groupingBy(Function<? super T, ? extends K> classifier) {
            return groupingBy(classifier, toList());
        }
    
    //两个入参
    public static <T, K, A, D>
        Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
                                              Collector<? super T, A, D> downstream) {
            return groupingBy(classifier, HashMap::new, downstream);
        }
    
    //三个入参(最终的方法)
    public static <T, K, D, A, M extends Map<K, D>>
        Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,
                                      Supplier<M> mapFactory,
                                      Collector<? super T, A, D> downstream) {...}
    

    在这里插入图片描述

    在第二个方法中我们可知,groupingBy接口调用自己的方法时创建了一个 HashMap ( HashMap::new)。因为**hashMap,是无序的 **,是根据key的hashcode进行hash,然后放入对应的地方。所以在按照一定顺序put进HashMap中,然后遍历出HashMap的顺序跟put的顺序不同。所以才出现了上述的问题。

    解决方案

    因为这三个方法都是public类型的,我们可以直接外部调用,而入参给一个有序的Map就可以了,我选择的是LinkedHashMap

    文章最后面会简单介绍LinkedHashMap

    示例代码如下
    //按照年纪倒序并分页
            Map<Integer, List<Student>> studentMap = students.stream()
                    .sorted(Comparator.comparing(Student::getAge).reversed())
                    .collect(Collectors.groupingBy(Student::getAge, LinkedHashMap::new, Collectors.toList()));
    
    结果如下:

    在这里插入图片描述

    LinkedHashMap的介绍

    • LinkedHashMap有序,HashMap无序

    • LinkedHashMap是HashMap的子类,内部维护了一个双向链表保证元素插入时候的顺序,其增删改查的时间复杂度为O(1)

    • LinkedHashMap的节点占用了更多的空间,包括指向前一个节点的指针before和指向后一个节点的after指针

    • LinkedHashMap默认使用插入顺序进行遍历,也可以使用访问顺序进行遍历。将accessOrder置为true即可

    在这里插入图片描述

    展开全文
  • 首先去api中查找问题原因,查看Java的java.util.stream 包 Collectors 类 groupingBy 方法实现,结果如下: //一个参数 public static <T, K> Collector<T, ?, Map<K, List<T>&
  • 默认groupingBy代码里会生成一个HashMap(hashMap是无序的,put的顺序与get的顺序不一致) HashMap是无序的,HashMap在put的时候是根据key的hashcode进行hash然后放入对应的地方。所以在按照一定顺序put进HashMap中...
  • 场景:excel导入,按照excel的顺序排序,需要去重并且做分组判断, 首先我们去重: List<OrdItem> ordItems=list.stream().filter(distinctByKey(o -> o.getPnId() + ";" + o.getCondition())).collect...
  • 一.groupingBy()的源码 public static <T, K, A, D> Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> ...
  • 创建排序字段带null的List(排序字段为User.name) List<User> nList = list.stream().sorted( Comparator.comparing(User::getName, Comparator.nullsFirst(String::compareTo))) .collect(Collectors.to...
  • myid = myData.stream().collect(Collectors.groupingBy(myEntity::getDataId)); Here mydata is sorted by desc order but after creating collections by group data id my list get sorted with ascending order...
  • 本篇是对博文进行汇总和拓展。 假设已有实体类 public class Student{ private Integer id; private String name; ... } 重点1:Collector...
  • userGroupMap = list.stream().collect(Collectors.groupingBy(User::getType));  System.out.println(userGroupMap); // // {李四=[User@6d06d69c], 马六=[User@4e25154f], 张三=[User@15db9742], 王五=...
  • groupingBy (XXX)使用对数据集进行分组,相关函数及使用示例如下: 1 . Collectors.summingInt(XXX)  summingInt源码:   /** * 静态函数 * 返回一个Collector接口,其可用于产生输入元素‘int...
  • Java8 stream 中利用 groupingBy 进行多字段分组求和

    万次阅读 多人点赞 2020-01-16 15:49:19
    Java8的groupingBy实现集合的分组,类似Mysql的group by分组功能,注意得到的是一个map 对集合按照单个属性分组、分组计数、排序 List<String> items = Arrays.asList("apple", "apple", "banana", ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,650
精华内容 4,660
关键字:

groupingby排序