问题:遍历时直接remove报异常
测试代码:
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
for (String key : map.keySet()) {
if ("b".equals(key)) {
map.remove(key);
}
}
运行时报错:
原因排查
使用增强for循环时,底层其实使用的是 Iterator。
在遍历过程中,如果直接调用 map.remove(),
会导致集合结构被修改。
Iterator 内部有一个 modCount 机制,用来检测结构是否被改变。
当检测到不一致时,就会抛出 ConcurrentModificationException。
解决方式1:使用Iterator删除
改成显式迭代器:
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> entry = iterator.next();
if ("b".equals(entry.getKey())) {
iterator.remove();
}
}
使用 iterator.remove() 不会报错。
解决方式2:使用removeIf
Java8 可以使用:
map.entrySet().removeIf(entry -> "b".equals(entry.getKey()));
内部也是安全删除。
补充测试
如果只是修改 value,不删除 key:
for (String key : map.keySet()) {
map.put(key, 100);
}
不会报错。
因为没有改变结构,只是修改已有 value。