ArrayList 的 ConcurrentModificationException

发布于 2024-09-08 11:25:55 字数 632 浏览 1 评论 0原文

我有以下代码:

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();
}

当我尝试运行它时,我得到 ConcurrentModificationException ,任何人都可以解释为什么会发生这种情况,即使代码在同一线程中运行?我该如何避免呢?

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?

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

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

发布评论

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

评论(6

﹉夏雨初晴づ 2024-09-15 11:25:55

如果您使用“foreach”循环浏览列表,则无法从列表中删除。您可以使用迭代器。替换:

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

为:

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

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

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();
    }
}
空城之時有危險 2024-09-15 11:25:55

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

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

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 Iterator and removing the item there.

Iterator<Item> iter = list.iterator();
while(iter.hasNext()) {
  Item blah = iter.next();
  if(...) {
    iter.remove(); // Removes the 'current' item
  }
}
红焚 2024-09-15 11:25:55

我喜欢逆序的 for 循环,例如:

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

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

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.

淡淡的优雅 2024-09-15 11:25:55

应该有一个支持此类操作的 List 接口的并发实现。

尝试 java.util.concurrent.CopyOnWriteArrayList.class

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

try java.util.concurrent.CopyOnWriteArrayList.class

沩ん囻菔务 2024-09-15 11:25:55

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

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

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();
}

While iterating through the loop, you are trying to change the List value in the remove() operation. This will result in 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();
}
自控 2024-09-15 11:25:55

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

检查这篇文章 ConcurrentHashMap

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

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

Check this post for ConcurrentHashMap

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

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