Java 8中如何通过Stream生成按值排序的HashMap?
解决HashMap按值排序后保持顺序的问题
首先得明确一个核心点:普通的HashMap是不维护插入顺序的,这就是为什么你用Collectors.toMap()得到的结果还是原顺序——因为默认它会创建普通HashMap,不管你流里的元素排序得多么整齐,存进去之后顺序就不受控制了。
要解决这个问题,你需要在收集Stream元素的时候,指定使用LinkedHashMap,它会严格保留元素的插入顺序,刚好能承接我们排序后的结果。修改后的代码如下:
return map.entrySet() .stream() .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, // 处理键重复的情况(如果你的原map不会有重复键,随便写个合并逻辑就行,比如保留旧值) (oldValue, newValue) -> oldValue, // 指定用LinkedHashMap来维护排序后的顺序 LinkedHashMap::new ));
关键细节说明:
Collectors.toMap()的第四个参数是一个Supplier,用来指定最终返回的Map类型。这里传入LinkedHashMap::new,就会生成一个能保留插入顺序的Map。- 第三个参数是键冲突的合并函数,因为理论上Stream处理时可能出现重复键(虽然原HashMap不会有,但做个兜底更稳妥),需要告诉程序怎么处理冲突。如果你的场景里绝对不会有重复键,写
(a,b)->a就足够。
额外简化技巧:
如果你用的是Java 8及以上版本,还可以把排序逻辑写得更简洁,用Comparator.reverseOrder()直接替换Collections.reverseOrder(),代码看起来更清爽:
return map.entrySet() .stream() .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (o, n) -> o, LinkedHashMap::new ));
最后再敲个黑板:别指望普通HashMap帮你保存顺序,它的设计初衷就不是做有序存储的,LinkedHashMap才是专门用来维护插入顺序的实现类~
内容的提问来源于stack exchange,提问作者cadebe
相关产品推荐
相关产品推荐

