首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Map 集合九大核心問題深度解析與最佳實務

     編輯:Java 相關知識

0. Map 轉 List 三種視圖

// Key 列表
List<K> keyList = new ArrayList<>(map.keySet());

// Value 列表
List<V> valueList = new ArrayList<>(map.values());

// Entry 列表 (鍵值對)
List<Map.Entry<K, V>> entryList = new ArrayList<>(map.entrySet());

1. 高效遍歷:EntrySet 遍歷

// 推薦:單次查找同時取得 Key/Value
for (Map.Entry<K, V> entry : map.entrySet()) {
    K key = entry.getKey();
    V value = entry.getValue();
}

// Iterator 寫法 (JDK 1.5 風格)
Iterator<Map.Entry<K, V>> it = map.entrySet().iterator();
while (it.hasNext()) {
    Map.Entry<K, V> entry = it.next();
    // ...
}

**為何優於 keySet 遍歷?** keySet 需每次 `map.get(key)` 查找,EntrySet 直接持有引用,效能提升明顯。

2. 依 Key 排序

方案一:List + Comparator

List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
Collections.sort(list, (e1, e2) -> e1.getKey().compareTo(e2.getKey()));

方案二:TreeMap (自動排序)

SortedMap<K, V> sortedMap = new TreeMap<>((k1, k2) -> k1.compareTo(k2));
sortedMap.putAll(map);

**注意**:Key 必須實作 `Comparable` 或提供 `Comparator`。

3. 依 Value 排序

List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
Collections.sort(list, (e1, e2) -> e1.getValue().compareTo(e2.getValue()));

同理可用 Lambda 簡化:`Comparator.comparing(Map.Entry::getValue)`

4. 靜態常量 Map 線程安全初始化

問題:可變性風險

// ❌ 危險:外部仍可修改
public static final Map<String, String> MAP = new HashMap<>();
static { MAP.put("1", "one"); }
Test.MAP.put("3", "three"); // 編譯通過,運行時修改成功!

正確:不可變 Map

// ✅ 安全:真正不可變
private static final Map<String, String> MAP;
static {
    Map<String, String> temp = new HashMap<>();
    temp.put("1", "one");
    temp.put("2", "two");
    MAP = Collections.unmodifiableMap(temp);
}
// Test.MAP.put("3", "three"); // 拋出 UnsupportedOperationException

5. 三大實作類核心差異

特性HashMapTreeMapHashtableLinkedHashMap
順序無序Key 排序無序插入/存取順序
Null Key允許 1 個不允許不允許允許 1 個
Null Value允許允許不允許允許
線程安全否否是 (同步)否
效能最快較慢 (紅黑樹)最差略慢於 HashMap
適用場景一般用途需排序舊代碼/線程安全需保持順序 (LRU)

6. 反向查找:雙向 Map

JDK 無內建,需引入第三方庫:

  • Guava:`BiMap` / `HashBiMap.create()`
  • Apache Commons Collections:`BidiMap` / `DualHashBidiMap`

核心約束:**Key 與 Value 必須一對一唯一對應**。

7. Map 複製與同步

淺拷貝 (非同步)

Map<K, V> copied = new HashMap<>(originalMap);

同步包裝 (線程安全視圖)

Map<K, V> syncMap = Collections.synchronizedMap(originalMap);
// 迭代時必須手動同步!
synchronized (syncMap) {
    for (V value : syncMap.values()) { ... }
}

⚠️ 避免 Clone

Josh Bloch 不推薦 `clone()`:淺拷貝、型別擦除問題、介面契約模糊。**優先使用建構子或 `putAll` 複製。**

8. 空 Map 最佳實務

// 不可變空 Map (共享單例,零記憶體開銷)
Map<K, V> emptyMap = Collections.emptyMap();

// 可變空 Map
Map<K, V> mutableMap = new HashMap<>();

總結:Map 選型決策樹

  1. 需線程安全?→ `ConcurrentHashMap` (JDK 8+ 高效分段鎖)
  2. 需 Key 排序?→ `TreeMap`
  3. 需保持插入順序?→ `LinkedHashMap` (LRU 快取首選)
  4. 需保持存取順序?→ `LinkedHashMap(accessOrder=true)`
  5. 一般用途?→ `HashMap` (預設負載因子 0.75,初始容量預估資料量避免擴容)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved