Collectors.groupingBy分组后的排序问题
默认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取键值对时,是按照你放入的顺序来取的。

这就造成了一个List<Model>如果是有序的,在 groupingBy后 model的顺序是不可控的.
现在遇到这样一个场景
在CMS里,每个页面的模块是按顺序排放的,每个模块的内容也是按顺序的如
List<Model> list=Arrays.asList(m1,m2,m3)
现在需要对里面的元素分组,但是分组后的顺序也必须是 m1,m2,m3...中间可以缺少,但是不能乱序
以下是合法的 m1,m3 或者 m2,m3 但是不能 m3,m2
如以下代码 list的顺序是 id=2的在 id=1之前, 分组之后的访问也必须是id=2的在前才对
但是如果调用 默认的分组,就会发现 id=1的在前了 (在后的将要在前;在前的将要在后了)

输出总是
1
[A12,A11]
2
[A2,A21]
但是期望输出为
2 [A21,A2] 1 [A12,A11]
如果需要保持排序就不能使用默认的 方法了,必须使用 被注释的方法 (明确使用LinkedHashMap来保持顺序).
下面是groupingBy的参数说明

可以看到有三个参数,第一个参数就是key的Function了,第二个参数是一个map工厂,也就是最终结果的容器,一般默认的是采用的HashMap::new,最后一个参数很重要是一个downstream,类型是Collector,也是一个收集器,那就是说,这三个参数其实就是为了解决分组问题的
第一个参数:分组按照什么分类
第二个参数:分组最后用什么容器保存返回
第三个参数:按照第一个参数分类后,对应的分类的结果如何收集
其实一个参数的Collectors.groupingBy方法的 ,第二个参数默认是HashMap::new, 第三个参数收集器其实默认是Collectors.toList
Collectors.groupingBy分组后的排序问题的更多相关文章
- Java lambda 分组后多列求和
主要思路是reducing,可以像sql一样分组后多列求和处理成新对象等: select code,max(name)as name,sum(chengJi)as chengJi,sum(age)as ...
- java stream 处理分组后取每组最大
有一个需求功能:先按照某一字段分组,再按照另外字段获取最大的那个 Map<String, HitRuleConfig> configMap = configList.parallelStr ...
- group by 查询分组后 组的条数
比如select gid from table group by gid 查询时使用下面的方法查询条数 select count(distinct gid) from table 使用select c ...
- MySQL 分组后,统计记录条数
分组后,统计记录条数: SELECT num,count(*) AS counts from test_a GROUP BY num; 查询结果如下: 对num去重后的数量的统计: SELECT co ...
- MSSQL—按照某一列分组后取前N条记录
以前在开发的时候遇到过一个需求,就是要按照某一列进行分组后取前几条数据,今天又有同事碰到了,帮解决了之后顺便写一篇博客记录一下. 首先先建一个基础数据表,代码如下: IF OBJECT_ID(N'Te ...
- MSSQL 分组后取每组第一条(group by order by)
查询中经常遇到这种查询,分组后取每组第一条.分享下一个SQL语句: --根据 x 分组后.根据 y 排序后取第一条 select * from ( select ROW_NUMBER() over(p ...
- SQL 分组后取最小行号记录
本示例测试两个表联接查询后,分组并取分组后的最小行号记录 测试表: tb1表结构如下: CREATE TABLE [dbo].[tb1]( ) NOT NULL, ) NULL, ) NULL, CO ...
- (转)ThinkPHP3.0 使用分组后路径访问无效的解决方法!
注意,清除Runtime,就是清除缓存,很重要,妹的,调试了一下午,总是加上Home目录分组就找不到页面,直接放到action下就行,原来是缓存搞得鬼,另外要在入口文件开启‘APP_DEBUG’ 在T ...
- SQL Server 分组后取Top N
SQL Server 分组后取Top N(转) 近日,工作中突遇一需求:将一数据表分组,而后取出每组内按一定规则排列的前N条数据.乍想来,这本是寻常查询,无甚难处.可提笔写来,终究是困住了笔者好一会儿 ...
随机推荐
- 算法Sedgewick第四版-第3章Searching-搜索总结
- 数据预处理 center&scale&box-cox
http://stackoverflow.com/questions/33944129/python-library-for-data-scaling-centering-and-box-cox-tr ...
- 468C Hack it!
传送门 题目大意 分析 here 对于最后求p的过程我想再说一下 那个45就是最前一位分别是0~9,所以总贡献就是45乘上每一种数开头对应多少种情况 而后面的10则是他前面可以填多少不同的数对他做的贡 ...
- 不用EL表达式---实现product页面显示
产品页面显示 静态页面如下: <%@ page language="java" contentType="text/html; charset=UTF-8" ...
- 【Head First Java 读书笔记】(三)primitive主数据类型和引用
认识变量 变量有两种:primitive数数据类型和引用. 声明变量 Java注重变量.它不会让你将浮点数类型变量放进整数类型的变量中,除非你先跟编译器确认过数字可以损失掉精确度. 为了要让类型安全能 ...
- php 递归求得目录大小
/* * 递归求得目录大小 * @param $dir 目录 */ function dirsize($dir){ $allsize = 0; $handle = opendir($dir); whi ...
- 【转】ASCII码十进制、十六进制对照表
源地址:https://www.baidu.com/link?url=3bScEOF5BVXt7ptGDjBV5JmynXHqEh5lyut1vUx6vEM7qqPY1vtbO22Vvy7xUoFd& ...
- C# Winform下一个热插拔的MIS/MRP/ERP框架(多语言方案)
个别时候,我们需要一种多语种切换方案. 我的方案是这样的: 1.使用文本文本存储多语言元素,应用程序启动时加载到内存表中: 2.应用程序启动时从配置文件加载语种定义: 3.所有窗体继承自一个Base基 ...
- [Swift实际操作]九、完整实例-(5)创建BaseViewController作为控制器的基类
本文将给项目中的所有视图控制器,创建一份基类.该基类用来定义一些共用的属性和方法. 首先在用来放置视图控制器类的文件夹上点击鼠标右键,打开右键 菜单. 选择[New File]创建文件选项. 在弹出的 ...
- Azure KUDU工具
Azure网站提供了一个比较不错可以用来对我们的网站进行分析的工具------KUDU,下面我们就来看看这个工具主要能为我们做些啥,啥时候使用它. 如何打开KUDU KUDU所展现的强大功能 如何打开 ...