Iterarot迭代删除
Java集合一般调用删除方法都是集合的方法,例如:
List list = new ArrayList();
list.add(...);
list.remove(...);
但是,如果在循环的过程中调用集合的remove()方法,一般就会导致循环出错,例如:
for(int i=0;i<list.size();i++){????
???????? list.remove(...);
}
循环过程中list.size()的大小变化了,就导致了错误。这时会抛出异常ConcurrentModificationException().
?
所以,如果你想在循环语句中删除集合中的某个元素,就要用迭代器iterator的remove()方法,因为它的remove()方法不仅会删除元素,还会维护一个标志,用来记录目前是不是可删除状态.
今天发现一个现象。
/** * The modCount value that the iterator believes that the backing * List should have. If this expectation is violated, the iterator * has detected concurrent modification. */int expectedModCount = modCount;public boolean hasNext() { return cursor != size();}public E next() { checkForComodification(); try {E next = get(cursor);lastRet = cursor++;return next; } catch (IndexOutOfBoundsException e) {checkForComodification();throw new NoSuchElementException(); }}public void remove() { if (lastRet == -1)throw new IllegalStateException(); checkForComodification(); try {AbstractList.this.remove(lastRet);if (lastRet < cursor) cursor--;lastRet = -1;expectedModCount = modCount; } catch (IndexOutOfBoundsException e) {throw new ConcurrentModificationException(); }}final void checkForComodification() { if (modCount != expectedModCount)throw new ConcurrentModificationException();} }
?
?
?
?
??cursor标示着当前list的索引,不断地与list size比对。如果hasNext返回true,会紧接着执行next方法,在next方法中检查当前list有没有被修改过。?
????在list迭代过程中,如果删除一个元素,那么size就减一,hasNext提前结束,迭代不会到达list的最后一个元素。也就是说,如果在迭代到list倒数第二个元素时删除此元素,接下来的hasNext会返回false,迭代结束,不会进入next方法中做检查,也就不会出什么问题。而除此之外的其它情况下,hasNext都是true,接下来的next方法检查时会产生异常。
?
???