例子1:
List<Integer>list=new ArrayList<>(); list.add(1); list.add(2); list.add(2); list.add(3); list.add(4); list.add(5); for(int i=0;i<list.size();i++){ if(list.get(i)%2==0){ list.remove(list.get(i)); } } System.out.println(list);
輸出結果:
[1, 2, 3, 5]
分析:
第三個元素沒有remove 掉,跟蹤:
第一次循環
i=0 size=5 當前元素=1 不移除元素
i=1 size=5 當前元素=2 移除元素
i=2 size=4 當前元素=3 不移除元素
在remove 的過程中 size 是移動的,所以 第三個元素給漏掉了
例子2:
List<Integer>list=new ArrayList<>(); list.add(1); list.add(2); list.add(2); list.add(3); list.add(4); list.add(5); System.out.println(list);*/ for (Integer a:list){ if(a == 2){ list.remove(a); } }
拋出異常:
java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList$Itr.next(ArrayList.java:851) at com.student.eureka1.StudentEureka1ApplicationTests.contextLoads(StudentEureka1ApplicationTests.java:31)
原因:
拋出異常代碼
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
final void checkForComodification() {
// 是因為 modCount != expectedModCount 不相等
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
在使用for(Object obj:objList) 這種增強for 循環的時候,每次遍歷會進行hasNext 判斷,它會創建 List的遍歷器Iterator ,在創建的時候它會將 modCount 賦值給 expectedModCount 。並且調用Iterator 的 next 方法。
在沒有調用 list.remove(a); 方法前,expectedModCount 和 modCount是相等的。
當調用后 注意 list.remove(a); 調用的不是Iterator 的remove 方法,而是 ArrayList的remove 方法, ArrayList的remove 方法 只會更新 modCount 值,不會更新expectedModCount 值,所以不相等報錯
(簡單點就是說:你用了Iterator 遍歷 但是在里面不是用Iterator 的 remove 方法導致)
private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; }