List、Map等这类数据结构在日常开发中的使用不可谓不多,经常会有遍历的同时进行修改的情况。例如:1
2
3
4
5
6
7Integer[] numbers = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
List<Integer> list = new ArrayList<>(Arrays.asList(numbers));
for (Integer integer : list) {
if (integer % 5 == 0) {
list.remove(integer);
}
}
这段代码在执行的时候便会抛出异常:1
2
3
4Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at com.example.MyClass.main(MyClass.java:16)
这个异常出现通常是遍历一个集合的同时,在修改这个集合。看到next
方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public E next() {
this.checkForComodification();
int var1 = this.cursor;
if(var1 >= ArrayList.this.size) {
throw new NoSuchElementException();
} else {
Object[] var2 = ArrayList.this.elementData;
if(var1 >= var2.length) {
throw new ConcurrentModificationException();
} else {
this.cursor = var1 + 1;
return var2[this.lastRet = var1];
}
}
}
然后看到checkForComodification
:1
2
3
4
5final void checkForComodification() {
if(ArrayList.this.modCount != this.expectedModCount) {
throw new ConcurrentModificationException();
}
}
即当modCount 与 expectedModCount 不相等时,会抛 ConcurrentModificationException 异常
。其实很早之前就会碰到这个问题,使用Iterator
进行遍历和操作就不会出现这个问题了,但是一直没有深究其原因。