在日常 Java 开发中,经常会遇到这样一个需求:Map 需要按照 value 排序。
但 Java 标准库里的 Map 有一个特点:
HashMap:无序LinkedHashMap:按插入顺序TreeMap:只能按 key 排序
👉 没有一种 Map 天然支持按 value 排序。
因此,按 value 排序的核心思路是:
先对 Map 的 entry 进行排序,再构造一个有序的 Map。
下面总结几种最常用、最实用的实现方式。
一、使用 Stream 按 value 排序(Java 8+ 推荐)
这是目前最推荐、最简洁的写法。
1. 示例代码(升序)
Map<String, Integer> map = new HashMap<>();
map.put("apple", 3);
map.put("banana", 1);
map.put("pear", 2);
Map<String, Integer> sortedMap = map.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
System.out.println(sortedMap);
// {banana=1, pear=2, apple=3}
2. 降序排序
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
3. 关键点说明
entrySet().stream():对 Map 的 entry 进行流式处理sorted(...):按 value 排序LinkedHashMap::new:保证排序后的顺序不会被打乱
⚠️ 如果用
HashMap收集结果,排序会失效!
二、使用 List 排序(兼容性最好)
如果你使用的是 较老版本 Java,或者希望逻辑更直观,可以使用 List 排序。
示例代码
Map<String, Integer> map = new HashMap<>();
map.put("apple", 3);
map.put("banana", 1);
map.put("pear", 2);
List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
list.sort(Map.Entry.comparingByValue());
Map<String, Integer> result = new LinkedHashMap<>();
for (Map.Entry<String, Integer> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
System.out.println(result);
// {banana=1, pear=2, apple=3}
特点
- 代码清晰、易理解
- 不依赖 Stream
- 性能和 Stream 方式相当
三、value 相同再按 key 排序(进阶用法)
有些场景下,value 可能相同,需要一个稳定、可预期的顺序。
示例:先按 value,再按 key
Map<String, Integer> sortedMap = map.entrySet()
.stream()
.sorted(
Comparator.comparing(Map.Entry<String, Integer>::getValue)
.thenComparing(Map.Entry::getKey)
)
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
四、为什么不能直接用 TreeMap?
很多人会第一反应想到 TreeMap,但它只能按 key 排序。
如果强行用 value 作为比较条件:
- value 相同会导致 key 被覆盖
- 排序规则与 Map 语义冲突
👉 不推荐使用 TreeMap 来实现按 value 排序。
五、几种方式的对比总结
| 方式 | 推荐指数 | 说明 |
|---|---|---|
| Stream + LinkedHashMap | ⭐⭐⭐⭐⭐ | Java 8+ 首选,代码简洁 |
| List 排序 | ⭐⭐⭐⭐ | 兼容性好,逻辑直观 |
| TreeMap | ⭐ | 不适合按 value 排序 |
六、结论
按 value 排序 Map 的通用公式:
Map → entrySet → 排序 → LinkedHashMap
如果你的项目使用的是 Java 8 及以上版本,优先选择 Stream 写法;
如果更关注可读性或兼容性,List 排序同样是非常可靠的方案。
💡 小技巧:如果你经常写这种逻辑,可以封装成一个通用工具方法,减少重复代码。
