import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
public class MyList {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("S1");
al.add("S2");
al.add("S3");
al.add("S4");
Iterator<String> lir = al.iterator();
while (lir.hasNext()) {
System.out.println(lir.next());
}
al.add(2, "inserted");
while (lir.hasNext()) {
System.out.println(lir.next());
}
}
}
特定的代码会引发错误:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at collections.MyList.main(MyList.java:32)
答案 0 :(得分:6)
由于数组列表在创建Iterator
后被修改,因此发生了这种情况。
此ArrayList的迭代器和listIterator返回的迭代器 方法是快速失败的:如果列表在结构上被修改了 创建迭代器之后的时间,除了通过之外的任何方式 迭代器自己删除或添加方法,迭代器会抛出一个 ConcurrentModificationException的。因此,面对并发 修改,迭代器快速而干净地失败,而不是 在不确定的时间冒着任意的,非确定性的行为 在将来。
Iterator<String> lir = al.iterator(); // Iterator created
while (lir.hasNext())
System.out.println(lir.next());
al.add(2, "inserted"); // List is modified here
while (lir.hasNext())
System.out.println(lir.next());// Again it try to access list
这里你应该做什么在修改后创建新的迭代器对象。
...
al.add(2, "inserted");
lir = al.iterator();
while (lir.hasNext())
System.out.println(lir.next());
答案 1 :(得分:3)
您正在修改Collection,然后尝试使用相同的迭代器。
再次获取Collection iterator
al.add(2, "inserted");
Iterator<String> lirNew = al.iterator();
while (lirNew.hasNext()) {
System.out.println(lirNew.next());
}
或使用ListIterator
ArrayList<String> al = new ArrayList<String>();
al.add("S1");
al.add("S2");
al.add("S3");
al.add("S4");
ListIterator<String> lir = al.listIterator();
while (lir.hasNext()) {
System.out.println(lir.next());
}
lir.add("insert");
while (lir.hasNext()) {
System.out.println(lir.next());
}
答案 2 :(得分:0)
在实例化迭代器之后,将对象添加到列表中。这将更改内部类AbstractList $ Itr.class中modCount的值。迭代器的next()方法将调用checkForComodification()方法,该方法抛出一个ConcurrentModificationException。这就是所谓的失败快速。
//add in abstractList
public void add(int index, E element) {
if (index<0 || index>size)
throw new IndexOutOfBoundsException();
checkForComodification();
l.add(index+offset, element);
expectedModCount = l.modCount;
size++;
modCount++; //modCount changed
}
在AbstractList $ Itr
中int expectedModCount;
public E next() {
checkForComodification(); // cause ConcurrentModificationException
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
private void checkForComodification() {
if (l.modCount != expectedModCount) //modCount not equals to itr.expectedModCount
throw new ConcurrentModificationException();
}
在添加后重做此代码:
al.add(2, "inserted");
lir = al.iterator();