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(); } } ... |
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();