我处于一种非常特殊的状态。我有一个如下所示的列表: -
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
现在当我进行多种类型的遍历时,比如使用高级for,iterator和normal for循环,下面是示例代码片段: -
1&GT;高级循环: -
try {
for(String a : list) {
System.out.println(a);
list.add("f");
}
} catch (Exception e) {
e.printStackTrace();
}
2 - ;迭代器: -
try {
Iterator<String> itr = list.iterator();
while(itr.hasNext()) {
System.out.println(itr.next());
list.add("f");
}
} catch (Exception e) {
e.printStackTrace();
}
3&GT;正常循环: -
for (int i=0;i<list.size();i++) {
System.out.println(list.get(i));
list.add("f");
}
现在,一个特殊的问题是,当使用高级for循环和迭代器时,我得到以下异常: -
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
the reason i know, that while iterating through a list, one cannot modify it parallely.
但是当我使用普通for循环时,它运行正常,我错过了什么?
请帮助!!! ..
答案 0 :(得分:7)
如果修改List,则会使从中创建的任何Iterator对象无效。高级循环(1)编译成与迭代器循环(2)几乎相同的代码,这意味着在幕后创建了一个Iterator对象。
ConcurrentMOdificationException的javadocs有更多细节。
如果要在迭代时添加,请使用
ListIterator listIter = ...
while(listIter.hasNext())
{
if(shouldAdd(iter.next())) {
iter.add(....)
}
}
答案 1 :(得分:3)
高级循环只是迭代器的语法糖。迭代器在运行checkForComodification()
时始终调用next()
。如果它看到您修改了列表,则此方法将抛出异常。
运行“Normal Loop”不提供检查修改计数的功能,因为你没有使用迭代器来循环,你是严格使用for循环结构。
答案 2 :(得分:0)
在列表上执行for循环会产生严重问题。您将获得重新读取的条目(删除之前的条目可能会导致此情况),您可能会获得IndexOutOfBoundsExceptions。使用CopyOnWriteArrayList作为并发安全列表而不会产生太多开销,具体取决于您的应用程序。如果您对列表有很多写入,请使用ConcurrentLinkedQueue,但要注意这就像一个队列,你只能做类似队列的东西,比如只添加到最后并从前面删除。
答案 3 :(得分:0)
您应该记住,Iterator的下一个方法抛出ConcurrentModificationException,但不是List的add方法抛出。这意味着,在循环中添加新元素时,实际上会修改列表。如果在添加新元素后退出循环,则不会抛出异常,并且该元素将添加到列表中。
否则,您可以使用Iterator的add和remove方法修改循环内的列表。