我前段时间看到一篇博客说如果你遇到concurrentmodificationexception
问题,请将arraylist转换为常规数组[],你就没事了。但它没有解释。
为什么会这样?
答案 0 :(得分:2)
当add
或remove
来自ArrayList
的元素时,您正在更改其结构。这将使在此更改之前初始化的任何iterator
无效。
数组没有真正的迭代器。 myArray[i] = myValue
只是一个赋值 - 它对数组的结构没有任何作用,并且是原子的,就像任何其他赋值一样。
答案 1 :(得分:1)
此类的迭代器和listIterator方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时候对列表进行结构修改,除了通过迭代器自己的remove或add方法之外,迭代器将抛出ConcurrentModificationException
。
请注意,此异常并不表示该对象已被其他线程同时修改。即使一个线程违反了对象的合同,也会抛出异常。
在Java中,尝试修改Iterator外部的Collections对象(ex, java.util.List)
时可能会发生ConcurrentModificationException。文档指出线程是可能的原因,但即使进行单线程编程也可以获得此异常。
以下代码抛出ConcurrentModificationException
,尽管在单个线程中执行。
List<String> mylist = new ArrayList<String>();
mylist.add("one");
Iterator<String> iterator = mylist.iterator();
while( iterator.hasNext() ) {
iterator.next();
mylist.remove(0); // throws the exception
}
对mylist的remove()
调用会干扰迭代器处理。在迭代时删除项目的正确方法是使用java.util.Iterator
的{{1}}方法(这与remove()
不同。
如果您维护一个应用程序并看到此异常,那么该错误很可能不像前面的代码块那样容易检测到。查找所有remove()调用并确保它们都在迭代器外部调用(如带索引的for循环)或迭代器java.util.List.remove(int))
(using iterator.remove()).
相关错误是IllegalStateException。如果在remove()之后没有推进迭代器,则会发生这种情况。
IllegalStateException
保持迭代器指针最新,一次使用iterator.next();
iterator.remove();
iterator.remove(); // will throw the error
操作一个元素;这来自Here.