在 Java 開發中,Map 是最常用的資料結構之一,但 Map 本身不保證順序。當我們需要根據 Value(值)對 Map 進行排序時,就需要一些額外的技巧。本文將詳細介紹如何實現 Map 按 Value 排序,並提供完整可執行的程式碼範例。
Map 本身不支援直接按 Value 排序,主要步驟如下:
import java.util.*;
public class MapSortByValue {
public static void main(String[] args) {
// 建立測試資料
Map<String, Integer> map = new HashMap<>();
map.put("apple", 50);
map.put("banana", 20);
map.put("orange", 80);
map.put("grape", 30);
map.put("pear", 10);
System.out.println("原始 Map(無序):");
map.forEach((k, v) -> System.out.println(k + " = " + v));
// 按 Value 升序排序
Map<String, Integer> sortedMap = sortByValue(map, true);
System.out.println("\n按 Value 升序排序:");
sortedMap.forEach((k, v) -> System.out.println(k + " = " + v));
// 按 Value 降序排序
Map<String, Integer> sortedMapDesc = sortByValue(map, false);
System.out.println("\n按 Value 降序排序:");
sortedMapDesc.forEach((k, v) -> System.out.println(k + " = " + v));
}
/**
* 根據 Map 的 Value 進行排序
* @param map 待排序的 Map
* @param ascending true 為升序,false 為降序
* @return 排序後的 LinkedHashMap(保持插入順序)
*/
public static <K, V extends Comparable<V>> Map<K, V> sortByValue(Map<K, V> map, boolean ascending) {
// 1. 將 entrySet 轉為 List
List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
// 2. 使用 Comparator 進行排序
list.sort((e1, e2) -> {
int result = e1.getValue().compareTo(e2.getValue());
return ascending ? result : -result;
});
// 3. 存入 LinkedHashMap 保持順序
Map<K, V> sortedMap = new LinkedHashMap<>();
for (Map.Entry<K, V> entry : list) {
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
}
使用 Stream API 可以更簡潔地完成排序:
// 升序
Map<String, Integer> sorted = map.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
// 降序
Map<String, Integer> sortedDesc = map.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
| 方法 | 時間複雜度 | 空間複雜度 | 適用場景 |
|---|---|---|---|
| Collections.sort + List | O(n log n) | O(n) | 通用、相容性好 |
| Stream API | O(n log n) | O(n) | Java 8+、程式碼簡潔 |
| TreeMap (按 Key 排序) | O(n log n) | O(n) | 需同步維護 Key 順序 |
Map 按 Value 排序的核心在於「轉 List → 排序 → 存 LinkedHashMap」。掌握這個模式後,無論是傳統寫法還是 Stream API,都能輕鬆應對各種排序需求。實務上建議根據專案 Java 版本選擇適合的寫法,並注意處理邊界情況。