【问题标题】:Why does one loop throw a ConcurrentModificationException, while the other doesn't?为什么一个循环会抛出 ConcurrentModificationException,而另一个不会?
【发布时间】:2010-03-07 18:17:01
【问题描述】:

我在编写旅行推销员程序时遇到了这个问题。对于内部循环,我尝试了

for(Point x:ArrayList<Point>) {
// modify the iterator
}

但是当向该列表添加另一个点时,会抛出 ConcurrentModicationException

但是,当我将循环更改为

for(int x=0; x<ArrayList<Point>.size(); x++) {
// modify the array
}

循环运行良好,没有抛出异常。

都是for循环,为什么一个会抛出异常而另一个不会呢?

【问题讨论】:

标签: java iterator concurrentmodification


【解决方案1】:

正如其他人所解释的,迭代器检测到对底层集合的修改,这是一件好事,因为它可能会导致意外行为。

想象一下这个修改集合的无迭代器代码:

for (int x = 0; list.size(); x++)
{
  obj = list.get(x);
  if (obj.isExpired())
  {
    list.remove(obj);
    // Oops! list.get(x) now points to some other object so if I 
    // increase x again before checking that object I will have 
    // skipped one item in the list
  }
}

【讨论】:

  • 我选择了您的答案,因为您展示了与通过 get() 访问相比,迭代时可能出现的问题
【解决方案2】:

第一个例子使用了迭代器,第二个没有。它是检查并发修改的迭代器。

【讨论】:

    【解决方案3】:

    第一个代码使用迭代器,因此不允许修改集合。您使用 x.get(i) 访问每个对象的第二个代码,因此不使用迭代器,因此允许修改

    【讨论】:

      【解决方案4】:

      您无法在迭代 List 时对其进行修改,就像在第一个示例中所做的那样。在第二个中,您只需有一个常规的for 循环。

      【讨论】:

        【解决方案5】:

        如果您运行代码并观察,您会发现循环的第一次迭代运行良好,但第二次抛出 ConcurrentModicationException

        if 是因为next() 方法检查元素的数量是否没有变化。

        有关详细说明,请参阅http://javaadami.blogspot.com/2007/09/enhanced-for-loop-and.html

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-05
          • 2011-06-19
          • 2014-02-25
          • 1970-01-01
          • 2016-06-20
          相关资源
          最近更新 更多