遍历列表时出现 ConcurrentException

发布于 2024-11-01 16:22:36 字数 1174 浏览 0 评论 0原文

我现在的状态很奇特。我有一个如下所示的列表:-

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");

现在,当我进行多种类型的遍历时,例如使用高级 for、迭代器和普通 for 循环,下面是示例代码片段:-

1>高级循环:-

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>正常循环:-

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 循环时,它就可以正常工作,我错过了什么吗?

请帮忙!!!...

I am in a very peculiar state. I have a list something like below :-

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");

Now when i do multiple type of traversing, like using advanced for, iterator, and normal for loop, below are the sample code snippets :-

1> Advanced Loop :-

try {
    for(String a : list) {
        System.out.println(a);
        list.add("f");
    }
} catch (Exception e) {
    e.printStackTrace();
}

2> Iterator :-

try {
    Iterator<String> itr =  list.iterator();
    while(itr.hasNext()) {
        System.out.println(itr.next());
        list.add("f");
    }
} catch (Exception e) {
    e.printStackTrace();
}

3> Normal Loop :-

for (int i=0;i<list.size();i++) {
    System.out.println(list.get(i));
    list.add("f");
}

Now, the peculiar problem is, that when using advanced for-loop and iterator, i get the following exception : -

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.

but when i use the normal for loop, then it works properly, Am i missing something??

Please Help!!!..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

九八野马 2024-11-08 16:22:36

如果修改 List,则会导致从它创建的任何 Iterator 对象失效。高级循环 (1) 编译为与迭代器循环 (2) 几乎相同的代码,这意味着在幕后创建了一个 Iterator 对象。

ConcurrentMOdificationException 的 javadocs 有更多详细信息。

如果您想在迭代时添加,请使用

ListIterator listIter = ...
while(listIter.hasNext())
{
    if(shouldAdd(iter.next())) {
        iter.add(....)
    }
}

If you modify a List, it invalidates any Iterator objects created from it. The advanced loop (1) compiles to nearly the same code as the iterator loop (2), meaning that there is an Iterator object created behind the scenes.

The javadocs for ConcurrentMOdificationException have more details.

If you want to add while iterating, use

ListIterator listIter = ...
while(listIter.hasNext())
{
    if(shouldAdd(iter.next())) {
        iter.add(....)
    }
}
七禾 2024-11-08 16:22:36

高级循环只是迭代器的语法糖。每当运行 next() 时,迭代器总是调用 checkForCommodification()。如果此方法发现您修改了列表,它将引发异常。

运行“正常循环”不提供检查修改计数的功能,因为您没有使用迭代器进行循环,而是严格使用 for 循环构造。

The advanced loop is just syntactic sugar for the iterator. The iterator always calls checkForComodification() whenever it runs next(). This method will throw an exception if it sees that you modified the list.

Running the "Normal Loop" does not provide this functionality of checking the modification count because you aren't using an iterator to loop, you are strictly using the for loop construct.

夏见 2024-11-08 16:22:36

对列表进行 for 循环会产生严重的问题。您将重新读取条目(删除先前的条目可能会导致此情况),并且可能会遇到 IndexOutOfBoundsExceptions。使用 CopyOnWriteArrayList 进行并发- 安全列表没有太多开销,具体取决于您的应用程序。如果您对列表有很多写入,请使用 ConcurrentLinkedQueue,但请注意,这就像一个队列,你只能用它做类似队列的事情,比如只添加到末尾并从前面删除。

Doing a for loop on the list will create serious problems. You'll get entries being re-read (deleting a previous entry might cause this) and you might get IndexOutOfBoundsExceptions. Use CopyOnWriteArrayList for a concurrent-safe list with not that much overhead, depending on your application. If you have many writes to the list, use ConcurrentLinkedQueue, but be aware that this acts like a queue and you can only do queue-like stuff with it like only adding to the end and removing from the front.

荆棘i 2024-11-08 16:22:36

您应该记住,ConcurrentModificationException 是由 Iterator 的 next 方法引发的,而不是由 List 的 add 方法引发的。这意味着,当您在循环中添加新元素时,列表实际上会被修改。如果在添加新元素后退出循环,则不会引发异常,并且该元素会添加到列表中。

否则,您可以使用迭代器的添加和删除方法来修改循环内的列表。

You should keep in mind that the ConcurrentModificationException is thrown by the Iterator's next method, but not by the List's add method. This means, the list is actually modified when you add a new element in the loop. If you quit the loop after adding a new element, there is no exception thrown and the element is added to the list.

Otherwise you can use Iterator's add and remove method to modify the list inside the loop.

青衫负雪 2024-11-08 16:22:36
    List<String> list = new ArrayList<String>();
    list.add("a");
    list.add("b");
    Iterator<String> itr =  list.iterator();
    while(itr.hasNext()) {
        System.out.println(itr.next());
       itr.add("f");
    }

而不是直接使用列表对象。您可以使用 Iterator() 类的 add()、remove() 来解决 ArrayList() 中的此错误。

而不是使用 List; list = new ArrayList();

use

   List<String> list = new CopyOnWriteArrayList<String>();

主要原因是ArrayList不是线程安全的,而CopyOnWriteArrayList是线程安全的。

java文档参考:

ArrayList - https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html

CopyOnWriteArrayList - https://docs.oracle.com/javase/7/docs/api /java/util/concurrent/CopyOnWriteArrayList.html

如果您遵循上述方法,那么所有代码​​片段都将起作用。

    List<String> list = new ArrayList<String>();
    list.add("a");
    list.add("b");
    Iterator<String> itr =  list.iterator();
    while(itr.hasNext()) {
        System.out.println(itr.next());
       itr.add("f");
    }

Instead of directly using the list object. you can use add(),remove() of the Iterator() class to resolve this error in ArrayList().

Instead of using List<String> list = new ArrayList<String>();

use

   List<String> list = new CopyOnWriteArrayList<String>();

The main reason is ArrayList is not thread safety whereas CopyOnWriteArrayList is thread safety.

java docs reference:

ArrayList -https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html

CopyOnWriteArrayList-https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArrayList.html

If you have follow the above approach then all the code snippets will work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文