1. 程式人生 > >ArrayList的迭代器原始碼分析

ArrayList的迭代器原始碼分析

呼叫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(應該是儲存元素的陣列)變數。

當外部類這些變數發生變化他也會跟著發生變化。沒有什麼安全隱患啊?

網路上說,當返回迭代器後,集合傳到迭代器資料,迭代器資料就固定了,也就是隻知道返回迭代器之前的集合元素。

再修改集合中的元素迭代器不知道。所以定義了併發修改異常。但原始碼中並不是這樣,而是隨外部類變化的變數。