遍历Collection,避免在循环中删除对象时避免ConcurrentModificationException [英] Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop

查看:99
本文介绍了遍历Collection,避免在循环中删除对象时避免ConcurrentModificationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们都知道,由于ConcurrentModificationException,您无法执行以下操作:

We all know you can't do the following because of ConcurrentModificationException:

for (Object i : l) {
    if (condition(i)) {
        l.remove(i);
    }
}

但这显然有时有效,但并非总是如此.这是一些特定的代码:

But this apparently works sometimes, but not always. Here's some specific code:

public static void main(String[] args) {
    Collection<Integer> l = new ArrayList<>();

    for (int i = 0; i < 10; ++i) {
        l.add(4);
        l.add(5);
        l.add(6);
    }

    for (int i : l) {
        if (i == 5) {
            l.remove(i);
        }
    }

    System.out.println(l);
}

这当然会导致:

Exception in thread "main" java.util.ConcurrentModificationException

即使没有多个线程在执行此操作.无论如何.

Even though multiple threads aren't doing it. Anyway.

此问题的最佳解决方案是什么?如何在不引发此异常的情况下循环地从集合中删除项目?

What's the best solution to this problem? How can I remove an item from the collection in a loop without throwing this exception?

我还在这里使用任意的Collection,不一定是ArrayList,因此您不能依赖get.

I'm also using an arbitrary Collection here, not necessarily an ArrayList, so you can't rely on get.

推荐答案

Iterator.remove() is safe, you can use it like this:

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

// This is a clever way to create the iterator and call iterator.hasNext() like
// you would do in a while-loop. It would be the same as doing:
//     Iterator<String> iterator = list.iterator();
//     while (iterator.hasNext()) {
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
    String string = iterator.next();
    if (string.isEmpty()) {
        // Remove the current element from the iterator and the list.
        iterator.remove();
    }
}

请注意, Iterator.remove() 是在迭代过程中修改集合的唯一安全方法;如果在迭代进行过程中以任何其他方式修改基础集合,则行为不确定.

Note that Iterator.remove() is the only safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.

来源: docs.oracle>集合接口

同样,如果您有ListIterator并想添加项,则可以使用

And similarly, if you have a ListIterator and want to add items, you can use ListIterator#add, for the same reason you can use Iterator#remove — it's designed to allow it.

在您的情况下,您尝试从列表中删除,但是如果尝试在迭代其内容的同时将put转换为Map,则存在相同的限制.

In your case you tried to remove from a list, but the same restriction applies if trying to put into a Map while iterating its content.

这篇关于遍历Collection,避免在循环中删除对象时避免ConcurrentModificationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆