public Iterator<E> iterator() {
return new Itr();
}
属性
int cursor; // 下一个要返回的元素的下标
int lastRet = -1; // 最后一个要返回元素的下标 没有元素返回 -1
int expectedModCount = modCount; //期望的 modCount
Itr的hasNext() 方法
public boolean hasNext() {
return cursor != size;
}
Itr的next()方法
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];
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
在迭代的时候,会校验modCount是否等于expectedModCount,
不等于就会抛出著名的ConcurrentModificationException异常。什么时候会抛出ConcurrentModificationException?
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
for (int i = 0; i < 10; i++) {
arrayList.add(i);
}
remove(arrayList);
System.out.println(arrayList);
}
public static void remove(ArrayList<Integer> list) {
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
Integer number = iterator.next();
if (number % 2 == 0) {
// 抛出ConcurrentModificationException异常
list.remove(number);
}
}
}
list.remove(number); 当这行代码执行后,modCount++, expectedModCount还是为原来的值,所以会发生ConcurrentModificationException异常
那怎么写才能不抛出ConcurrentModificationException?很简单,将list.remove(number);换成iterator.remove();即可。why?请看Itr的remove()源码…
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();
}
}