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

Java 遍歷 Map 的四種核心方式:效能對比、適用場景與最佳實踐

     編輯:Java 相關知識

Map 遍歷是 Java 開發高頻操作。本文系統整理四種核心遍歷方式,深度分析 HashMap 與 TreeMap 下的效能差異,提供選型決策指南。

四種核心遍歷方式完整程式碼

Map map = new HashMap<>();
map.put("a", "A");
map.put("b", "B");
map.put("c", "C");

// 1. keySet + 迭代器 (舊式)
Iterator it1 = map.keySet().iterator();
while (it1.hasNext()) {
    String key = it1.next();
    String value = (String) map.get(key);
    System.out.println(value);
}

// 2. keySet + 增強 for (最常用)
for (String key : map.keySet()) {
    String value = (String) map.get(key);
    System.out.println(value);
}

// 3. entrySet + 迭代器
Iterator> it2 = map.entrySet().iterator();
while (it2.hasNext()) {
    String value = (String) it2.next().getValue();
    System.out.println(value);
}

// 4. entrySet + 增強 for (推薦同時取 key/value)
for (Map.Entry entry : map.entrySet()) {
    String key = entry.getKey();
    String value = (String) entry.getValue();
    System.out.println(key + "=" + value);
}

// 5. 僅遍歷 values
for (Object value : map.values()) {
    System.out.println(value);
}

效能深度分析:HashMap vs TreeMap

HashMap (雜湊表,O(1) 存取)

場景推薦方式理由
同時需 key & valueentrySet一次性取得 Entry 物件,避免額外 map.get(key) 雜湊查找
僅需 keykeySetentrySet 會建立無用的 Entry 物件
僅需 valuevalues()最直接,無 key 開銷

關鍵洞察:當 key 極簡單 (如短字串、Integer) 時,keySet + get() 可能因避免建立 Entry 物件而略快 (~10%);但 key 複雜 (長字串、自定義物件、高碰撞) 時,entrySet 優勢明顯。綜合建議預設使用 entrySet。

TreeMap (紅黑樹,O(log n) 存取)

場景推薦方式理由
同時需 key & valueentrySet (壓倒性優勢)樹查找 get(key) 為 O(log n),累積開銷遠大於 entrySet 一次遍歷
僅需 keykeySet同 HashMap
僅需 valuevalues()同 HashMap

結論:TreeMap 必須使用 entrySet 遍歷 key-value,效能差距可達數倍。

Java 8+ Stream API 寫法 (函數式風格)


// 同時處理 key/value
map.forEach((k, v) -> System.out.println(k + "=" + v));

// 轉換為 List
List values = map.values().stream()
    .map(Object::toString)
    .collect(Collectors.toList());

// 過濾與轉換
Map filtered = map.entrySet().stream()
    .filter(e -> e.getKey().startsWith("a"))
    .collect(Collectors.toMap(Map.Entry::getKey, e -> (String)e.getValue()));

執行緒安全陷阱 ⚠️

遍歷過程中修改 Map 會拋出 ConcurrentModificationException (除非使用 ConcurrentHashMap)。

  • 需邊遍歷邊刪除:使用 Iterator.remove() 或 ConcurrentHashMap
  • 需邊遍歷邊新增/修改:收集待處理鍵值至臨時集合,遍歷結束後批次更新
  • 高併發讀寫:直接用 ConcurrentHashMap,其迭代器為弱一致性,不拋出 CME

總結選型速查表

需求Map 類型最佳方式備註
Key + ValueHashMapentrySet + for-each預設首選
Key + ValueTreeMapentrySet + for-each強制,效能差距大
僅 Key所有keySet
僅 Value所有values()
需刪除所有Iterator.remove()或 ConcurrentHashMap
函數式/串流所有forEach / stream()Java 8+

原文補充說明

原文測試顯示:HashMap 下 key 為簡單字串時 keySet 比 entrySet 快 ~10% (避免建立 Entry);但 key 複雜時 entrySet 勝出。TreeMap 下 entrySet 完勝。建議:預設用 entrySet,唯有確認 key 極簡單且僅遍歷 HashMap 時考慮 keySet。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved