Collectors.groupingBy分组后的排序问题

Stella981
• 阅读 1761

默认groupingBy代码里会生成一个HashMap(hashMap是无序的,put的顺序与get的顺序不一致)

  • HashMap是无序的,HashMap在put的时候是根据key的hashcode进行hash然后放入对应的地方。所以在按照一定顺序put进HashMap中,然后遍历出HashMap的顺序跟put的顺序不同(除非在put的时候key已经按照hashcode排序号了,这种几率非常小)
  • 单纯的HashMap是无法实现排序的,这的排序是指,我们将键值对按照一定的顺序put进HashMap里,然后在进行取键值对的操作的时候,是按照put进去的顺序把键值对取出来的。
  • JAVA在JDK1.4以后提供了LinkedHashMap来帮助我们实现了有序的HashMap!LinkedHashMap取键值对时,是按照你放入的顺序来取的。

Collectors.groupingBy分组后的排序问题

这就造成了一个List如果是有序的,在 groupingBy后 model的顺序是不可控的.

现在遇到这样一个场景

在CMS里,每个页面的模块是按顺序排放的,每个模块的内容也是按顺序的如 

List list=Arrays.asList(m1,m2,m3)

现在需要对里面的元素分组,但是分组后的顺序也必须是 m1,m2,m3...中间可以缺少,但是不能乱序

以下是合法的 m1,m3  或者  m2,m3 但是不能 m3,m2

如以下代码 list的顺序是  id=2的在 id=1之前, 分组之后的访问也必须是id=2的在前才对

但是如果调用 默认的分组,就会发现 id=1的在前了 (在后的将要在前;在前的将要在后了)

Collectors.groupingBy分组后的排序问题

输出总是

1

[A12,A11]

2

[A2,A21]

但是期望输出为

2 [A21,A2]    1 [A12,A11]

如果需要保持排序就不能使用默认的 方法了,必须使用 被注释的方法 (明确使用LinkedHashMap来保持顺序).

下面是groupingBy的参数说明

Collectors.groupingBy分组后的排序问题

可以看到有三个参数,第一个参数就是key的Function了,第二个参数是一个map工厂,也就是最终结果的容器,一般默认的是采用的HashMap::new,最后一个参数很重要是一个downstream,类型是Collector,也是一个收集器,那就是说,这三个参数其实就是为了解决分组问题的

  1. 第一个参数:分组按照什么分类

  2. 第二个参数:分组最后用什么容器保存返回

  3. 第三个参数:按照第一个参数分类后,对应的分类的结果如何收集

其实一个参数的Collectors.groupingBy方法的 ,第二个参数默认是HashMap::new, 第三个参数收集器其实默认是Collectors.toList

点赞
收藏
评论区
推荐文章
HashMap的理解
HashMap在Map.Entry静态内部类实现中存储keyvalue对。HashMap使用哈希算法,在put和get方法中,它使用hashCode()和equals()方法。当我们通过传递keyvalue对调用put方法的时候,HashMap使用KeyhashCode()和哈希算法来找出存储keyvalue对的索引。Entry存储在LinkedL
Wesley13 Wesley13
2年前
java ConcurrentHashMap和CopyOnWriteArrayList解决并发问题
ConcurrentHashMap一、hashtable、hashmap、ConcurrentHashMap1、线程不安全的HashMap因为多线程环境下,使用Hashmap进行put操作会引起死循环,导致CPU利用率
BichonCode BichonCode
3年前
Java的其他Map
一、LinkedHashMap1.1应用场景HashMap是无序的,当我们希望有顺序地去存储keyvalue时,就需要使用LinkedHashMap了。1.2插入顺序和访问顺序LinkedHashMap默认的构造参数是默认 插入顺序的,就是说你插入的是什么顺序,读出来的就是什么顺序,但是也有访问顺序,就是说你访问了一个key,这个
Stella981 Stella981
2年前
HashMap 初始化时赋值
一般初始化一个map并且给map赋值的写法:HashMap<String,StringmapnewHashMap<String,String();map.put("name","test");map.put("age","20");但是我想在初始化的时候就直接给map中set值。
Stella981 Stella981
2年前
HashMap中神奇的h & (length
众所周知,HashMap是基于Hash表的Map接口实现,HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap中主要是通过key的hashCode来计算hash值的,只要hashCode相同,计算出来的hash值就一样。但是知道了Hash值之后,又是怎么确定出key在数组中的索引呢?根据源码得知如下方法static
Stella981 Stella981
2年前
HashMap源码分析 JDK1.8
本文按以下顺序叙述:HashMap的感性认识.官方文档中对HashMap介绍的解读.到源码中看看HashMap这些特性到底是如何实现的.把源码啃下来有一种很爽的感觉,相信你读完后也能体会到~如发现有误,欢迎指出.<h3id1在开始之前,先通过图例对HashMap建立感性认识</h3
Stella981 Stella981
2年前
HashMap,LinkedHashMap,TreeMap的有序性
HashMap实际上是一个链表的数组。HashMap的一个功能缺点是它的无序性,被存入到HashMap中的元素,在遍历HashMap时,其输出是无序的。如果希望元素保持输入的顺序,可以使用LinkedHashMap替代。LinkedHashMap继承自HashMap,具有高效性,同时在HashMap的基础上,又在内部增加了一个链表,用以存
Wesley13 Wesley13
2年前
Java HashMap的工作原理
面试的时候经常会遇见诸如:“java中的HashMap是怎么工作的”,“HashMap的get和put内部的工作原理”这样的问题。本文将用一个简单的例子来解释下HashMap内部的工作原理。首先我们从一个例子开始,而不仅仅是从理论上,这样,有助于更好地理解,然后,我们来看下get和put到底是怎样工作的。我们来看个非常简单的例子。有一个”国家”(Coun
Stella981 Stella981
2年前
HashMap1.7和1.8,红黑树原理!
jdk1.7概述HashMap基于Map接口实现,元素以键值对的方式存储,并允许使用null键和null值,但只能有一个键作为null,因为key不允许重复,另外HashMap不能保证放入元素的数据,它是无序的,和放入的顺序并不能相同,HashMap是线程不安全的。继承关系publicclassH
Wesley13 Wesley13
2年前
Java HashMap的工作原理
面试的时候经常会遇见诸如:“java中的HashMap是怎么工作的”,“HashMap的get和put内部的工作原理”这样的问题。本文将用一个简单的例子来解释下HashMap内部的工作原理。首先我们从一个例子开始,而不仅仅是从理论上,这样,有助于更好地理解,然后,我们来看下get和put到底是怎样工作的。我们来看个非常简单的例子。有一个”国家”(Coun