ArrayList源碼解讀三之Iterator(迭代器)

在ArrayList的iterator()方法中就只有創建一個類Itr。

<code>    public Iterator 
iterator() {
return new Itr();
}
/<code>

我們查看一下Itr這個類,發現它是實現了 Iterator接口的。

<code>    private class Itr implements Iterator {
int cursor;
int lastRet = -1;
int expectedModCount = modCount;
Itr() {}
}
/<code>

我們瞭解方法之前先了解變量作用

  • cursor:表示光標,其作用是確定此時光標在位置的
  • lastRet:默認是無元素狀態,其作用是確定位置有元素的。**( lastRet=-1表示此位置無元素,lastRet表示此位置有元素)**
  • modCount:記錄ArrayList的操作次數
  • expectedModCount:記錄Iterator的操作次數

清楚瞭解變量的作用,我們接下來了解方法

(一)checkForComodification函數

作用:判斷ArrayList的操作次數與Iterator的操作次數是否相一致,不一致則拋出異常

<code>    final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}/<code>

(二)next函數

<code>    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];
}/<code>

步驟:

  1. 進行判斷操作次數是否一致。
  2. 判斷光標是否大於ArrayList數組的元素數量。
  3. 將ArrayList進行賦值給新的Object數組。
  4. 判斷光標是否大於ArrayList數組的大小。
  5. 對光標進行+1。
  6. 將lastRet賦值,並且返回。

(三)remove函數

<code>    public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}/<code>

步驟:

  1. 判斷lastRet的位置是否有元素
  2. 進行判斷操作次數是否一致。
  3. 對ArrayList的數組進行移除當前lastRet位置的元素。
  4. 對光標進行移動。
  5. 將lastRet此時位置設置無元素。
  6. 更新expectedModCount修改次數。

注意:在使用過next函數前提下才能使用remove()函數,不然會拋出IllegalStateException()異常。

(四)forEachRemaining函數

作用:與foreach類似,forEachRemaining遍歷Iterator的所有元素

<code>    public void forEachRemaining(Consumer super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}/<code>

步驟:

  1. requireNonNull判斷consumer對象是否為空指針。
  2. 獲取ArrayList中的元素數量、獲取光標位置、創建新的Oject數組。
  3. 光標超過ArrayList的數量或者數組長度會返回或者拋出異常。
  4. 光標不等於ArrayList的數量以及Iterator和ArrayList操作次數一致的情況下進行循環。
    (consumer.accept裡面是空函數,具體函數內容模塊需要傳進來的consumer實現)
  5. 對光標,以及lastRet賦值。
  6. 判斷Iterator和ArrayList操作次數是否一致。

以上的話就是ArrayList中Iterator的源碼實現。


分享到:


相關文章: