一、错误原因
在List、Set、Map三种集合循环中,新增
或删除
了本集合内的元素。
Java会在循环结束时,比较当前集合中的元素个数与循环前元素的个数,不一致则抛出这个异常。
如下HashMap的循环源码:
二、举例与解决
1. ArrayList循环中删除元素
错误代码
public void removeInForeach() {
List<String> strings = new ArrayList<>(Arrays.asList("a", "b", "c", "b"));
for (String str : strings) {
if ("b".equals(str)) {
strings.remove(str);
}
}
System.out.println(strings);
}
使用removeIf()
方法解决
public void removeInForeach() {
List<String> strings = new ArrayList<>(Arrays.asList("a", "b", "c", "b"));
strings.removeIf("b"::equals);
System.out.println(strings);
}
2. HashMap循环中删除元素
错误示例
public void removeFailure() {
Map<String, String> map = new HashMap<>(16);
map.put("aa", "1");
map.put("bb", "2");
Set<String> keyList = map.keySet();
for (String key : keyList) {
if ("aa".equals(key)) {
map.remove(key);
}
}
}
使用entrySet的removeIf()
方法解决
public void removeSuccess2() {
Map<String, String> map = new HashMap<>(16);
map.put("aa", "1");
map.put("bb", "2");
map.entrySet().removeIf(next -> "aa".equals(next.getKey()));
System.out.println(map);
}
3. HashMap循环中新增元素
错误代码
public void foreach() {
Map<String, String> map = new HashMap<>(16);
map.put("aa", "1");
map.put("bb", "2");
map.forEach((k, v) -> {
if ("aa".equals(k)) {
map.put("AA", v);
}
});
}
定义临时map
暂存要添加的元素,最后调用putAll()
添加暂存的元素
public void foreachAdd() {
Map<String, String> map = new HashMap<>(16);
Map<String, String> tmpMap = new HashMap<>(16);
map.put("aa", "1");
map.put("bb", "2");
map.forEach((k, v) -> {
if ("aa".equals(k)) {
tmpMap.put("AA", v);
}
});
map.putAll(tmpMap);
System.out.println(map);
}