itr.hasNext():通過判斷 cursor(游標) != size(長度)來決定是否結束循環,cursor(游標) 初始是0 每次經過 itr.next() +1;當cursor==size時 會跳出循環;
itr.next(): 看源代碼可以發現每次在next()調用后,都會先調用checkForComodification()這個方法;
checkForComodification(): 主要作用是判斷itr迭代器數據是否和list一致,
有兩個參數,
第一個 modCount 集合結構變動次數,如:一開始你add調用了7次,那么這個數就是7,
第二個 expectedModCount 在調用iterator()方法時,初始化值等于modCount ,
這個方法判斷當 modCount != expectedModCount 時 拋出異常ConcurrentModificationException,如果你調用迭代器的remove方法,expectedModCount 會重新賦值,但是你調用的是list的remove方法,那么modCount 就會+1 而expectedModCount 不變,這就會造成 modCount != expectedModCount;
//第二種刪除方式 for(int i = 9;i>=0;i--){//使用倒序刪除方式同樣不會發生異常 list.get(i); list.remove(i); }ArrayList中的remove有兩個同名方法,只是入參不同,這里看的是入參為Object的remove方法)是怎么實現的:
public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; } PRivate void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work }可以看到會執行System.arraycopy方法,導致刪除元素時涉及到數組元素的移動。所以將元素從數組中刪除,并且將后一個元素移動至當前位置,導致下一次循環遍歷時后一個字符串并沒有遍歷到,所以無法刪除。針對這種情況可以倒序刪除的方式來避免:
新聞熱點
疑難解答