迭代器是一种比较“轻量级”的对象,因为创建代价较小,而且比较方便,因此都喜欢使用迭代器来遍历集合,但不建议使用迭代器来删除元素
下面进行分析一下迭代器的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不是一个东西!!!)