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

Java 遍歷 Map 的四種核心姿勢:從 EntrySet 到 Lambda 表達式

     編輯:Java 相關知識

前言

Map 作為 Java 集合框架的核心成員,遍歷操作頻率極高。JDK 5 引入增強 for 循環,JDK 8 帶來 Lambda 與 Stream API,讓遍歷方式更加多元。本文系統梳理四種主流遍歷姿勢,對比性能與適用場景,助你寫出更優雅、高效的代碼。

姿勢一:KeySet 遍歷 —— 最基礎也最常見

Map<String, Object> map = new HashMap<>();
map.put("name", "張三");
map.put("age", 25);

// 僅需 Key 時
for (String key : map.keySet()) {
    System.out.println("Key: " + key);
}

// 需要 Value 時(需二次查找)
for (String key : map.keySet()) {
    Object value = map.get(key);
    System.out.println(key + " = " + value);
}

⚠ 注意:若 Map 定義為原始類型 Map map = new HashMap(),泛型擦除導致 Key 只能用 Object 接收,建議始終使用泛型聲明。

姿勢二:EntrySet 遍歷 —— 單次查找獲取 Key-Value

Map<Integer, String> weekMap = new LinkedHashMap<>();
weekMap.put(1, "週一");
weekMap.put(2, "週二");
// ... 至 7

for (Map.Entry<Integer, String> entry : weekMap.entrySet()) {
    System.out.print(entry.getKey() + ":" + entry.getValue() + "\t");
}
// 輸出:1:週一  2:週二  3:週三  4:週四  5:週五  6:週六  7:週日
  • 優勢:一次迭代同時獲取 Key/Value,避免 map.get(key) 的額外查找開銷
  • 推薦場景:需要同時訪問鍵值對、或對性能敏感的熱點代碼

姿勢三:JDK 8 forEach + Lambda —— 代碼最精簡

// 單行式
weekMap.forEach((k, v) -> System.out.println(k + "=" + v));

// 多行式
weekMap.forEach((k, v) -> {
    if (k % 2 == 0) System.out.println("雙數鍵: " + k + " -> " + v);
});
  • 內部實現仍基於 entrySet() 迭代器,性能與姿勢二相近
  • 適用於簡單業務邏輯,複雜邏輯建議用傳統 for 保持可讀性

姿勢四:Stream API —— 函數式處理與並行化

// 篩選、轉換、收集
List<String> result = weekMap.entrySet().stream()
    .filter(e -> e.getKey() > 3)
    .map(e -> e.getKey() + ":" + e.getValue())
    .collect(Collectors.toList());

// 並行處理大數據量 Map
weekMap.entrySet().parallelStream()
    .forEach(entry -> heavyCompute(entry.getKey(), entry.getValue()));
  • 適合「遍歷+篩選+轉換+聚合」的管道式操作
  • 並行流需注意線程安全與開銷,小數據量反而較慢

性能對比與選型建議

方式時間複雜度適用場景推薦指數
keySet + getO(n) + n×O(1)僅需 Key、或 Map 極小★★☆
entrySet (for-each)O(n)通用首選、需 Key+Value★★★★★
forEach + LambdaO(n)簡單邏輯、代碼簡潔★★★★☆
Stream APIO(n)複雜管道操作、並行需求★★★☆☆

避坑指南

  1. 遍歷中修改 Map:直接 map.put()/remove() 會拋 ConcurrentModificationException。解決:收集待處理 Key 到列表,遍歷後再操作;或用 ConcurrentHashMap。
  2. Null 值處理:HashMap 允許 null Key/Value,Hashtable/ConcurrentHashMap 不允許,遍歷時需防空指針。
  3. 保持順序:需插入序用 LinkedHashMap,需自然序用 TreeMap,HashMap 無序。

總結

日常開發中,entrySet 增強 for 循環 是性能與可讀性的最佳平衡點;Lambda forEach 適合簡單邏輯快速編寫;Stream API 則是複雜數據處理管道的利器。根據業務複雜度、團隊代碼風格靈活選擇,才是成熟工程師的態度。

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