public interface Iterable<T> { Iterator<T> iterator(); default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } default Spliterator<T> spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); } }
public interface Iterator<E> { boolean hasNext(); E next(); default void remove() { throw new UnsupportedOperationException("remove"); } default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); } }
List<String> famousList = new ArrayList<>(); famousList.add("Sheldon"); famousList.add("Sherlock"); famousList.add("Batman"); famousList.add("Optimus Prime"); for (String famous : famousList) { famousList.remove(famous); }
上面的代碼之因此會拋出ConcurrentModificationException異常的緣由:ide
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(); } } @Override @SuppressWarnings("unchecked") 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(); } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
從以上代碼可知,當調用next()函數的時候,會先調用checkForComodification函數來檢查集合的modCount與expectedModCount是否相等,若不相等則拋出錯誤。來到這裏就能知道,在使用iterator遍歷集合的時候,使用集合的remove、add等函數,就會致使modCount和expectedModCount不一致,從而致使異常拋出。函數
Iterator<String> iterator = famousList.iterator(); for (;iterator.hasNext();){ String famous=iterator.next(); System.out.println(famous); if ("Batman".equals(famous)){ iterator.remove(); break; } } System.out.println(famousList.size());
或者:ui
for (int i = 0; i < famousList.size(); i++) { System.out.println(famousList.get(i)); if ("Batman".equals(famousList.get(i))){ famousList.remove(famousList.get(i)); break; } } System.out.println(famousList.size());
public interface ListIterator<E> extends Iterator<E> { boolean hasNext(); E next(); //判斷cursor前是否有元素 boolean hasPrevious(); //得到cursor前一個元素,而且cursor後退一位 E previous(); //返回cursor元素的index int nextIndex(); //返回cursor前一個元素的index int previousIndex(); void remove(); //更新上一次調用next、previous返回的元素,也就是iterator最後一次操做的元素,沒有調用next、previous前調用的話會拋出IllegalStateExceptiony異常 void set(E e); //向cursor前插入元素 void add(E e); }
public ListIterator<E> listIterator() { return new ListItr(0); } //返回指定cursor位置的listIterator public ListIterator<E> listIterator(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index); }
相比Iterator,多了add、set以及previous等方法。this