Java ArrayList 的 ConcurrentModificationException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3184883/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 17:13:41  来源:igfitidea点击:

ConcurrentModificationException for ArrayList

javacollectionsconcurrency

提问by mabuzer

I have the following piece of code:

我有以下一段代码:

private String toString(List<DrugStrength> aDrugStrengthList) {
    StringBuilder str = new StringBuilder();
        for (DrugStrength aDrugStrength : aDrugStrengthList) {
            if (!aDrugStrength.isValidDrugDescription()) {
                aDrugStrengthList.remove(aDrugStrength);
            }
        }
        str.append(aDrugStrengthList);
        if (str.indexOf("]") != -1) {
            str.insert(str.lastIndexOf("]"), "\n          " );
        }
    return str.toString();
}

When I try to run it, I get ConcurrentModificationException, can anyone explain why it happens, even if the code is running in same thread? And how could I avoid it?

当我尝试运行它时,我得到ConcurrentModificationException,即使代码在同一线程中运行,谁能解释为什么会发生?我怎么能避免呢?

采纳答案by Konrad Garus

You can't remove from list if you're browsing it with "for each" loop. You can use Iterator. Replace:

如果您使用“for each”循环浏览列表,则无法从列表中删除。您可以使用Iterator. 代替:

for (DrugStrength aDrugStrength : aDrugStrengthList) {
    if (!aDrugStrength.isValidDrugDescription()) {
        aDrugStrengthList.remove(aDrugStrength);
    }
}

With:

和:

for (Iterator<DrugStrength> it = aDrugStrengthList.iterator(); it.hasNext(); ) {
    DrugStrength aDrugStrength = it.next();
    if (!aDrugStrength.isValidDrugDescription()) {
        it.remove();
    }
}

回答by bragboy

While iterating through the loop, you are trying to change the List value in the remove() operation. This will result in ConcurrentModificationException.

在迭代循环时,您试图更改 remove() 操作中的 List 值。这将导致 ConcurrentModificationException。

Follow the below code, which will achieve what you want and yet will not throw any exceptions

按照下面的代码,这将实现你想要的,但不会抛出任何异常

private String toString(List aDrugStrengthList) {
        StringBuilder str = new StringBuilder();
    List removalList = new ArrayList();
    for (DrugStrength aDrugStrength : aDrugStrengthList) {
        if (!aDrugStrength.isValidDrugDescription()) {
            removalList.add(aDrugStrength);
        }
    }
    aDrugStrengthList.removeAll(removalList);
    str.append(aDrugStrengthList);
    if (str.indexOf("]") != -1) {
        str.insert(str.lastIndexOf("]"), "\n          " );
    }
    return str.toString();
}

回答by Edward Dale

Like the other answers say, you can't remove an item from a collection you're iterating over. You can get around this by explicitly using an Iteratorand removing the item there.

就像其他答案所说的那样,您无法从正在迭代的集合中删除项目。您可以通过显式使用 anIterator并在那里删除项目来解决此问题。

Iterator<Item> iter = list.iterator();
while(iter.hasNext()) {
  Item blah = iter.next();
  if(...) {
    iter.remove(); // Removes the 'current' item
  }
}

回答by idiotgenius

there should has a concurrent implemention of List interface supporting such operation.

应该有支持这种操作的 List 接口的并发实现。

try java.util.concurrent.CopyOnWriteArrayList.class

试试 java.util.concurrent.CopyOnWriteArrayList.class

回答by froman

I like a reverse order for loop such as:

我喜欢循环的相反顺序,例如:

int size = list.size();
for (int i = size - 1; i >= 0; i--) {
    if(remove){
        list.remove(i);
    }
}

because it doesn't require learning any new data structures or classes.

因为它不需要学习任何新的数据结构或类。

回答by Suganthan Madhavan Pillai

We can use concurrent collection classes to avoid ConcurrentModificationException while iterating over a collection, for example CopyOnWriteArrayList instead of ArrayList.

我们可以在迭代集合时使用并发集合类来避免 ConcurrentModificationException,例如 CopyOnWriteArrayList 而不是 ArrayList。

Check this post for ConcurrentHashMap

检查这篇文章以获取 ConcurrentHashMap

http://www.journaldev.com/122/hashmap-vs-concurrenthashmap-%E2%80%93-example-and-exploring-iterator

http://www.journaldev.com/122/hashmap-vs-concurrenthashmap-%E2%80%93-example-and-exploring-iterator