【问题标题】:ConcurrentModificationException when removing an object from ArrayList [duplicate]从 ArrayList 中删除对象时出现 ConcurrentModificationException [重复]
【发布时间】:2013-12-14 22:30:06
【问题描述】:

我的课程:

class Game{
     ArrayList<Block> blocks;
public ArrayList<Block> getBlocks(){return blocks;};
}
class Block{
    if(conditon) {
    game.getBlocks().remove(this);
}
}

我有这些类,ArrayList 包含超过 10 个 Block 实例,如果 Block 类中删除当前块的条件为真,我需要从 ArrayList 中删除这个块,但我得到了 Exception..

【问题讨论】:

  • 请分享一个产生异常的简短完整示例。
  • 在谷歌中粘贴你的问题的标题,然后点击它返回的第一个链接。

标签: java arraylist


【解决方案1】:

如果故障快速迭代器检测到 在迭代期间进行了修改,它抛出 ConcurrentModificationException,这是一个未经检查的异常。您很可能在同一个循环中迭代和修改您的集合。

另外,java.util 包中的集合类都返回快速失败的迭代器, 这意味着他们假设一个集合不会改变它的内容 线程遍历其内容的时间。

【讨论】:

    【解决方案2】:

    在迭代Arraylist 时,您不能删除任何项目。如果您想在迭代时删除一个项目,您可以将已删除的项目添加到新创建的ArrayList 中。 willBeRemovedList 迭代完成后,您可以一次删除所有这些。

    【讨论】:

      【解决方案3】:

      ArrayList class 的文档清楚地告诉我们原因以及如何避免它:

      这个类的迭代器和listIterator返回的迭代器 方法是快速失败的:如果列表在任何结构上被修改 迭代器创建后的时间,除了通过 迭代器自己的删除或添加方法,迭代器会抛出一个 并发修改异常。因此,面对并发 修改,迭代器快速而干净地失败,而不是 在不确定的时间冒着任意的、不确定的行为的风险 未来。

      【讨论】:

        【解决方案4】:

        ConcurrentModificationException 被迭代器抛出,因为您修改了一个列表,而他无法获得 nextElement,因为他不知道他正在迭代的列表到底发生了什么。

        for (Block block : blocks) {
          blocks.remove(block);
        }
        

        这将在for 循环尝试获取修改列表的下一个元素时抛出异常,因为Iterator 在循环遍历列表的开头被实例化,迭代器将无法选择正确的下一个元素并抛出异常。

        但是,您可以从正在迭代的列表中删除当前元素,但应该通过 Iterator 本身来完成。你会做这样的事情:

        for (Iterator<Block> iterator = blocks.iterator(); iterator.hasNext(); iterator.next()){
          iterator.remove();
        }
        

        【讨论】:

          猜你喜欢
          • 2019-05-12
          • 2014-06-03
          • 2018-01-09
          • 2013-03-02
          • 2021-12-15
          • 2020-12-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多