尝试在迭代时删除元素时出现ConcurrentModificationException

时间:2015-07-31 15:16:49

标签: java concurrentmodification

我正在编写一个代码,用于确定是否可以食用某个项目。如果它是可以食用的,我会回复一条消息。

这是我的代码:

java.util.ConcurrentModificationException:
null(in java.util.ArrayList$itr)

当我运行上述内容时,我得到:

jQuery.ajax()

这个错误是什么意思?我该怎么做才能解决这个问题?

4 个答案:

答案 0 :(得分:0)

您需要使用Iterator从数组

中删除项目

所以在你的情况下

Iterator<Item> i = items.iterator();
while (i.hasNext()) {
   Item s = i.next();
   if(s.isEdible()){
            message = "Yum, that was tasty!";
            i.remove();
        }
        else{
            message = "That is not edible.";
        }
    }
}

答案 1 :(得分:0)

您可以在eat()中创建一个临时ArrayList,添加您要在该临时列表中删除的所有项目,在完成items循环后,只需执行{ {1}}

答案 2 :(得分:0)

使用迭代器循环遍历集合时,您无法对集合本身进行更改(即删除,替换,添加)。这导致迭代器中的数据变坏,&#39;这就是你收到这个例外的原因。即使在非并发迭代中也会发生这种情况,并且在大多数语言中都可以使用迭代器。

相反,你可以做两件事之一。

  1. 首先,如果索引是可索引的集合并以这种方式删除数据,则可以循环索引。这是合法的。

  2. 另一个选择是添加一些逻辑来创建一个删除队列&#39;。然后,您可以遍历删除队列并从原始集合中删除对象(或使用集合中的removeAll()方法)

答案 3 :(得分:0)

迭代时不能修改集合。有办法解决这个问题(例如,使用迭代器),还有其他方法可以解决不需要迭代器的问题。这是一个:

  1. 收集不良物品
  2. 删除不良内容
  3. 伪代码:

    // Collect the bad items
    ArrayList<Item> blacklist = new ArrayList<>();
    for (Item item : items) {
        if (!isEdible(item)) {
            blackList.add(item)
        }
    }
    
    // Remove the bad items
    for (Item item : blacklist) {
        myList.remove(item);
    }
    

    您的代码还有其他问题。

    • String item被视为参数但从未使用过。
    • 每次打电话给eat()时,你的角色都会吃掉他整个背包里的每一件物品,因为你会遍布整个收藏品并取出所有可食用物品。
    • itemString,但itemsItem的集合。为什么类型不匹配?

    从您在问题中的描述中可以明显看出,您只想吃一个项目(可能是传入的项目)。只要检查一下这个物品是否在你的背包里,如果是的话,检查它是否可以食用,如果是的话,就吃吧。

    public void eat(Item item) {
        if (items.contains(item)) {
            if (item.isEdible()) {
                items.remove(item);
                message = "Yum";
            } else {
                message = "Can't eat it";
            }
        } else {
            message = "Can't find it";
        }
    }