Java Map 循環(huán)遍歷方式與性能對(duì)比實(shí)例詳解
1. Map 遍歷的基礎(chǔ)準(zhǔn)備
Map<String, String> map = new HashMap<>();
map.put("A", "Apple");
map.put("B", "Banana");
map.put("C", "Cherry");
2. 七種遍歷方式詳解
2.1 entrySet + for-each(推薦)
最經(jīng)典、最通用的方式。
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + " -> " + value);
}
優(yōu)點(diǎn):同時(shí)獲取 key 和 value,性能最佳(只遍歷一次)
缺點(diǎn):代碼稍長(zhǎng)(但可讀性好)
2.2 keySet + for-each(不推薦)
只取 key,再通過(guò) key 獲取 value。
for (String key : map.keySet()) {
String value = map.get(key);
System.out.println(key + " -> " + value);
}
缺點(diǎn):需要兩次查找(迭代 + get),HashMap 中性能約為 entrySet 的一半。
2.3 只遍歷 value
for (String value : map.values()) {
System.out.println(value);
}
適用場(chǎng)景:只需要 value,不需要 key。
2.4 Iterator + entrySet(適合刪除操作)
Iterator<Map.Entry<String, String>> iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, String> entry = iter.next();
if ("B".equals(entry.getKey())) {
iter.remove(); // 安全刪除
}
}
優(yōu)點(diǎn):遍歷過(guò)程中可以安全刪除元素。
2.5 forEach (Java 8+ Lambda)
map.forEach((key, value) -> System.out.println(key + " -> " + value));
優(yōu)點(diǎn):代碼簡(jiǎn)潔優(yōu)雅
缺點(diǎn):不能修改外部非 final 變量(需要變通),不支持 break/return 提前終止(必須拋出異常)。
2.6 Stream API(函數(shù)式處理)
map.entrySet().stream()
.filter(e -> e.getKey().startsWith("A"))
.forEach(e -> System.out.println(e.getKey() + " -> " + e.getValue()));
適用場(chǎng)景:需要鏈?zhǔn)竭^(guò)濾、映射、聚合等操作。
2.7 僅 JDK 8+ 的 compute / merge 等(函數(shù)式計(jì)算)
雖然不屬于“遍歷”,但適用于邊遍歷邊計(jì)算新值。
map.replaceAll((key, value) -> value.toUpperCase());
3. 性能對(duì)比(HashMap 測(cè)試)
| 方式 | 100萬(wàn)條目耗時(shí)(ms) | 推薦指數(shù) |
|---|---|---|
| entrySet for-each | 32 | ????? |
| Iterator + entrySet | 33 | ???? |
| forEach (Lambda) | 34 | ????? |
| Stream API | 38 | ???? |
| keySet + get | 67 | ?? |
測(cè)試環(huán)境:JDK 17, HashMap<String,String>, 100萬(wàn)條目,平均取三次。
4. 并發(fā)場(chǎng)景下的遍歷
4.1 ConcurrentHashMap
ConcurrentHashMap<String, String> cmap = new ConcurrentHashMap<>(); // 使用與 HashMap 相同的遍歷方式,但弱一致性 cmap.forEach((k, v) -> System.out.println(k));
4.2 遍歷時(shí)修改(避免 ConcurrentModificationException)
- 普通 HashMap:只能用
Iterator.remove() - ConcurrentHashMap:支持安全遍歷,但無(wú)法保證立即看到最新數(shù)據(jù)
// 錯(cuò)誤示范(會(huì)拋異常)
for (String key : map.keySet()) {
if (condition) map.remove(key);
}
// 正確方式:Iterator 刪除
Iterator<Map.Entry<String,String>> it = map.entrySet().iterator();
while(it.hasNext()){
if(condition) it.remove();
}5. 最佳實(shí)踐總結(jié)
| 場(chǎng)景 | 推薦方式 |
|---|---|
| 需要 key + value | entrySet + for-each 或 forEach |
| 只需要 value | values() |
| 遍歷中刪除元素 | Iterator 或 ConcurrentHashMap |
| 函數(shù)式鏈?zhǔn)教幚恚ㄟ^(guò)濾、映射) | Stream API |
| 極端性能要求(百萬(wàn)級(jí)以上) | entrySet for-each |
| 代碼簡(jiǎn)潔且無(wú)刪除/中斷需求 | forEach (Lambda) |
6. 常見(jiàn)誤區(qū)與注意點(diǎn)
- 不要在 for-each 中直接
map.remove()→ 會(huì)拋ConcurrentModificationException - keySet + get 性能差 → 盡量使用
entrySet - Lambda forEach 無(wú)法
break→ 需要用Stream.findFirst()或普通循環(huán) - TreeMap / LinkedHashMap 的遍歷順序不同(默認(rèn)排序 / 插入順序),但遍歷寫(xiě)法一樣
7. 完整示例代碼
public class MapLoopDemo {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("Java", "17");
map.put("Python", "3.11");
map.put("Go", "1.20");
// 1. entrySet + for-each
System.out.println("=== entrySet ===");
for (var entry : map.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}
// 2. Java 8 forEach
System.out.println("=== forEach Lambda ===");
map.forEach((k, v) -> System.out.println(k + " : " + v));
// 3. Stream 過(guò)濾
System.out.println("=== Stream filter ===");
map.entrySet().stream()
.filter(e -> e.getKey().length() > 3)
.forEach(e -> System.out.println(e.getKey()));
}
}結(jié)語(yǔ)
Java Map 循環(huán)沒(méi)有“唯一正確”的方式,而是應(yīng)根據(jù)可讀性、性能、功能需求(刪除/中斷/并發(fā))做出選擇。日常開(kāi)發(fā)中,entrySet + for-each 或 forEach Lambda 足以覆蓋 90% 的場(chǎng)景;遇到復(fù)雜數(shù)據(jù)處理,優(yōu)先考慮 Stream;需要遍歷中刪除,務(wù)必使用 Iterator。
掌握這七種方式,就能輕松應(yīng)對(duì)所有 Map 遍歷場(chǎng)景。
到此這篇關(guān)于Java Map 循環(huán)遍歷方式與性能對(duì)比實(shí)例詳解的文章就介紹到這了,更多相關(guān)java map 循環(huán)遍歷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 深入探究Java中的HashMap為什么會(huì)產(chǎn)生死循環(huán)
- Java中Map循環(huán)遍歷的五種方法實(shí)現(xiàn)
- Java中的HashMap為什么會(huì)產(chǎn)生死循環(huán)
- Java8中forEach語(yǔ)句循環(huán)一個(gè)List和Map
- Java for循環(huán)Map集合優(yōu)化實(shí)現(xiàn)解析
- Java HashMap三種循環(huán)遍歷方式及其性能對(duì)比實(shí)例分析
- 詳解javaweb中jstl如何循環(huán)List中的Map數(shù)據(jù)
- 詳解Java中l(wèi)ist,set,map的遍歷與增強(qiáng)for循環(huán)
- java List循環(huán)與Map循環(huán)的總結(jié)
- Java Map的幾種循環(huán)方式總結(jié)
相關(guān)文章
springcloud nacos的賦值均衡和動(dòng)態(tài)刷新
nacos是一個(gè)分布式的配置中心和注冊(cè)發(fā)現(xiàn)中心,這篇文章主要介紹了springcloud nacos的賦值均衡和動(dòng)態(tài)刷新,需要的朋友可以參考下2024-05-05
SpringBoot中使用MyBatis-Plus詳細(xì)步驟
MyBatis-Plus是MyBatis的增強(qiáng)工具,簡(jiǎn)化了MyBatis的使用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2025-01-01
解決springboot自定義注解AOP在controller上導(dǎo)致controller注入失敗問(wèn)題
這篇文章主要介紹了解決springboot自定義注解AOP在controller上導(dǎo)致controller注入失敗問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
Java實(shí)現(xiàn)基于清除后分配規(guī)則的垃圾回收器詳解
垃圾回收是 Java 語(yǔ)言的一項(xiàng)重要特性,自動(dòng)管理對(duì)象內(nèi)存,防止內(nèi)存泄漏和野指針問(wèn)題,下面我們就來(lái)看看如何利用Java實(shí)現(xiàn)基于清除后分配規(guī)則的垃圾回收器吧2025-03-03
Java編程常見(jiàn)內(nèi)存溢出異常與代碼示例
這篇文章主要介紹了Java編程常見(jiàn)內(nèi)存溢出異常與代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11

