調用ArrayList的iterator方法後會返回可以操作集合的迭代器。
這是就有結合和迭代器兩種方式可以操作元素。
如果返回迭代器後再集合操作元素會拋出ConcurrentModificationException異常
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
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() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
這裏的checkForComodification方法就是檢測返回迭代器後,集合是否對元素進行操作:如 曾刪改 如果發生拋出異常
moCount變量的作用 : 是記錄集合對元素的增刪改的次數。
exceptedmodCount變量作用:當迭代器返回時就將集合對元素修改的次數(modCount)賦值給此變量。
當返回迭代器後,如果集合再進行修改元素操作modCount會累加,當調用迭代器的方法對元素修改時,會首先調用checkForCoundification方法判斷modCount和ExceptedmodCount是否一樣,不一樣代表返回迭代器後,集合有進行了修改元素操作,所以就需要拋出異常
至於爲什麼要拋出異常。我覺得沒有什麼意義,因爲next方法有依靠size,elentData(應該是存儲元素的數組)變量。
當外部類這些變量發生變化他也會跟着發生變化。沒有什麼安全隱患啊?
網絡上說,當返回迭代器後,集合傳到迭代器數據,迭代器數據就固定了,也就是隻知道返回迭代器之前的集合元素。
再修改集合中的元素迭代器不知道。所以定義了併發修改異常。但源碼中並不是這樣,而是隨外部類變化的變量。