Deep Understanding of ArrayList.iterator()

iterator often cause problems, because developers often do not know how it works. The following code is from source code of ArrayList.

One common problem is throwing java.util.ConcurrentModificationException. This exception is actually throw in the remove method. remove() has to be called after next(). if remove() is called before next(), the size of arraylist changes, modCount != expectedModCount is satisfied, and ConcurrentModificationException is thrown.

 
...
 
public Iterator<E> iterator() {
    return new Itr();
}
 
/**
 * An optimized version of AbstractList.Itr
 */
private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;
 
    public boolean hasNext() {
        return cursor != size;
    }
 
    @SuppressWarnings("unchecked")
    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];
    }
 
    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();
        }
    }
 
    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
}
 
...

1 thought on “Deep Understanding of ArrayList.iterator()”

  1. i think it throw ConcurrentModificationException that happens where follows:
    if (i >= elementData.length) throw new ConcurrentModificationException();
    that donot happen the place if (modCount != expectedModCount)throw new ConcurrentModificationException();

Leave a Comment