Thinking in java自讀筆記:Iterator的實現
阿新 • • 發佈:2018-11-05
迭代器是一種比較“輕量級”的物件,因為建立代價較小,而且比較方便,因此都喜歡使用迭代器來遍歷集合,但不建議使用迭代器來刪除元素
下面進行分析一下迭代器的3個主要方法:
1.Iterator.hasNext()
public boolean hasNext() {
return nextIndex < size;
}
這個較為簡單,直接判斷迭代器是否還有下一個元素,當迭代器在最後一個元素時,nextIndex==size;
2.Iterator.next()
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.item;
}
在這個方法中,checkForComodification()方法是一個”快速檢測失敗”的方法,程式碼如下:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
在remove()方法中,modCount和expectedModCount的值會同步變化,因此在正常情況下不會發生錯誤。如果在迭代過程中,直接對集合進行add()和remove()操作,會改變modCount的值,因此會報錯!。在next()方法中,lastReturned可以理解為”當前元素”。因為初始化一個Iterator時,lastReturned=null,只有呼叫一次next之後,lastReturned=next,則lastReturned的元素則變為了當前元素。
3.Iterator.remove()
public void remove() {
checkForComodification();
if (lastReturned == null)
throw new IllegalStateException();
Node<E> lastNext = lastReturned.next;
unlink(lastReturned);
if (next == lastReturned)
next = lastNext;
else
nextIndex--;
lastReturned = null;
expectedModCount++;
}
這個方法是很容易出錯的,在呼叫一次remove()之後,刪除掉lastReturned指向的元素,並且lastReturned為null,因此不能在迭代器裡面連續使用remove方法,remove方法不會影響next指向的位置(next和node.next不是一個東西!!!)