问题
List<Integer> list = IntStream.range(0, 10)
.boxed()
.collect(Collectors.toList());
// 增删都会报并发修改异常 ConcurrentModificationException
for(int i: list) {
list.add(2);
list.remove(1);
}
原因
ArrayList 维护一个继承自 AbstractList 的 modCount 变量,列表每次增删都会累加变量;
for 正序循环时,由 Iterator 迭代器接管列表,迭代器内部维护一个 modCount 变量复制,当列表增删时,列表 modCount 变化,报异常;
解决
- 倒序遍历
// 倒序增删
// 不适用迭代器
for(int i = list.size() - 1; i >= 0; i--) {
list.add(2);
list.remove(2);
}
- ArrayList 内部迭代器
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
// 初始化 lastRet 变量
iterator.next();
// 方法调用前必须调用 next(),通过 lastRet 下标操作
iterator.remove();
}
// 子迭代器,增加向前递归,add() 方法
ListIterator<Integer> iterator = list.listIterator();
while (iterator.hasNext()) {
iterator.next();
iterator.remove();
iterator.add(1);
iterator.add(1);
}
- 使用 CopyOnWriteArrayList
// 使用 CopyOnWriteArrayList
CopyOnWriteArrayList<Integer> copyOnWriteArrayList =
new CopyOnWriteArrayList(list);
for(int i: copyOnWriteArrayList) {
list.add(2);
list.remove(1);
}