遍历列表时获取ConcurrentException

时间:2011-04-13 04:52:25

标签: java list iterator for-loop foreach

我处于一种非常特殊的状态。我有一个如下所示的列表: -

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循环时,它运行正常,我错过了什么?

请帮助!!! ..

4 个答案:

答案 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方法修改循环内的列表。