为什么一个循环会抛出ConcurrentModificationException异常,而另一个不会?

10

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

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

但是,当我将另一个点添加到该列表中时,会导致抛出ConcurrentModificationException异常。

然而,当我将循环改为

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

循环正常运行且未引发异常。

两个循环都是for循环,为什么一个会引发异常而另一个不会呢?


可能与“循环删除列表”重复,链接如下:https://dev59.com/wHI-5IYBdhLWcg3wTWf4 - McDowell
5个回答

10

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

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

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
  }
}

2
我选择了您的答案,因为您展示了当进行迭代时可能会出现哪些问题,与通过使用 get() 进行访问相比。 - Jason

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

2
第一段代码使用了迭代器,因此不允许修改集合。而第二段代码通过x.get(i)访问每个对象,所以没有使用迭代器,因此可以进行修改。

0

0

在第一个示例中,您正在迭代的List是不允许被修改的。因此,在迭代期间修改列表是不被允许的。而在第二个示例中,您只是使用了一个普通的for循环。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接