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

java8 小技巧保证分组groupingBy后排序不变问题:遇到一个小问题,查询出来一组数据后,按照其中的属性进行groupBy分组,分组后要保证顺序不变。排查首先去api中查找解决//一个参数publicstatic<T,K>Collector<T,?,Map<K,List<T>>>groupingBy(Function<?superT,?ex…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

问题:

遇到一个小问题,查询出来一组数据后,按照其中的属性进行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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/171442.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • data pipeline是做什么_pycharm创建爬虫项目

    data pipeline是做什么_pycharm创建爬虫项目一.保存至MongoDBimportpymongoclassMongoPipeline(object):#初始化参数def__init__(self,mongo_uri,mongo_db):self.mongo_uri=mongo_uriself.mongo_db=mongo_db#以依赖注入的…

    2022年9月14日
  • html div 隐藏滚动条样式,div滚动条样式隐藏与显示

    html div 隐藏滚动条样式,div滚动条样式隐藏与显示DIV滚动条样式是可以设置的,CSS滚动条同样也可以显示与隐藏,对div设置滚动条,设置其横向滚动条和纵向滚动条样式应该怎么做呢?要设置CSS滚动条样式,需要用到overflow-y和overflow-x来设置div盒子对象右侧和底部滚动条效果。同时也可以使用CSS样式设置html框架iframe的滚动条隐藏,接下来为大家介绍。常规overflow怎么设置overflow-y:scroll总是显…

    2022年7月12日
  • 浙江八年级 python_如何看待浙江八年级将新增python编程以及数据结构等课程?…

    浙江八年级 python_如何看待浙江八年级将新增python编程以及数据结构等课程?…不是吧阿sir,这后浪来的有点快吧放观点:可以在教育中普及编程语言引导学生学习,但不能把它变成所有初中生的必修课你把VB这种过时东西扔掉,我举双手赞成;你让学有余力、对这方面感兴趣的同学在课余时间研习一下代码和算法,我对此是鼓励的;但是你把python拿过来强制所有人学,那这门课1)如果加入记分考试,那这在应试教育体系下纯粹是给学生增加负担(我们学校大一下刚学VB这种比python还要简单的语言,…

    2022年5月13日
  • 火车头采集器在线发布模块制作教程视频_火车头采集器收费与免费的区别

    火车头采集器在线发布模块制作教程视频_火车头采集器收费与免费的区别在线发布模块,就是采集器通过网站后台,发布文章,也就是说,把你手动在网站后台发布文章的整个过程包含登录网站后台,选择栏目,到后面的发布文章,这些步骤写到采集器里面,就是在线发布模块,然后规则采集到的值就通过标签名传递给在线发布模块,把数据提交到网站里去。我们借助抓包工具Fiddler(下载地址:http://www.locoy.com/Down/RelatedSoft/Fiddle

    2022年9月20日
  • 单片机 流水灯

    单片机 流水灯单片机流水灯一、简述  通过Proteus仿真单片机最小系统+流水灯的显示电路。用Keil编写相应执行文件。  源码、仿真电路图打包:链接:https://pan.baidu.com/s/1ZetoHZGz-jebnAd_BQGAUg密码:h8jc二、效果三、工程结构1、Keil编程2、仿真电路图四、源文件LiuShui.c文件#i…

    2022年5月1日
  • Oracle修改用户密码过期时间「建议收藏」

    Oracle修改用户密码过期时间「建议收藏」部署的Web应用突然无法登录系统,后台尝试重新启动看能不能恢复,发现启动时在数据库连接池部分报错,怀疑无法连接数据库。使用的是oracle数据库,通过plsql发现也无法连接,从报错可以看出应该是用户密码过期了,因此需要要修改用户密码。通过sysdba身份登录,修改用户密码:alteruserusernameidentifiedbypassword;为了避免密码再次过期,打算设…

    2022年7月28日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号