java 中 map 本身没有直接的 iterator,需要调用 .entryset().iterator() 获取键值对的迭代器进行遍历。这种方式允许在遍历时通过 iterator.remove() 安全地删除元素,且性能优于先获取 key 集合再逐个查找 value 的方式。

如何安全地在遍历过程中移除 Map 中的特定元素
使用 Iterator.remove() 是线程不安全环境下唯一安全的移除方式。直接调用 Map.remove() 会抛出 ConcurrentModificationException。以下代码演示了如何移除所有值为 null 的条目。

import java.util.*;
public class Main {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("a", "1");
map.put("b", null);
map.put("c", "3");
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> entry = it.next();
if (entry.getValue() == null) {
it.remove(); // 安全移除
}
}
System.out.println(map); // 输出: {a=1, c=3}
}
}
为什么不建议用 for-each 循环直接操作 Map 结构
for-each 循环底层也是使用 Iterator,但它不支持在循环体内调用 remove() 以外的修改操作。如果尝试在 for-each 中调用 map.remove(),会触发快速失败机制。因此,涉及结构变更时,必须显式获取 Iterator。
立即学习“Java免费学习笔记(深入)”;

import java.util.*;
public class Main {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("x", "10");
map.put("y", "20");
try {
for (Map.Entry<String, String> entry : map.entrySet()) {
if ("x".equals(entry.getKey())) {
map.remove(entry.getKey()); // 错误:抛出 ConcurrentModificationException
}
}
} catch (Exception e) {
System.out.println("Caught: " + e.getClass().getSimpleName());
}
}
}
基于 entrySet 遍历时的内存开销与类型安全
相比 keySet() 遍历,entrySet() 避免了重复的哈希计算和查找,每次迭代直接返回 Entry 对象。Entry 包含 key 和 value,无需二次访问 Map。对于大型 Map,这种差异显著。此外,Entry 接口强制了类型检查,防止误操作。


















