Почему один цикл бросает ConcurrentModificationException, в то время как другой не делает?

Я столкнулся с этим при записи программы Коммивояжера. Для внутреннего цикла я попробовал a

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

но когда добавление другой точки к тому списку привело к a ConcurrentModicationException быть брошенным.

Однако, когда я изменил цикл на

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

цикл хорошо работал, не выдавая исключение.

Оба для циклов, итак, почему каждый выдает исключение, в то время как другой не делает?

10
задан Damian 26 April 2014 в 21:33
поделиться

4 ответа

Как объясняли другие, итератор обнаруживает изменения в базовой коллекции, и это хорошо, поскольку может вызвать неожиданное поведение.

Представьте себе этот код без итераторов, который изменяет коллекцию:

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
  }
}
9
ответ дан 3 December 2019 в 21:21
поделиться

В первом примере используется итератор, во втором - нет. Именно итератор проверяет одновременную модификацию.

6
ответ дан 3 December 2019 в 21:21
поделиться

первый код использует итератор, поэтому модификация коллекции не разрешена. Во втором коде вы обращаетесь к каждому объекту с помощью x.get(i), поэтому не используете итератор, модификации, таким образом, разрешены

2
ответ дан 3 December 2019 в 21:21
поделиться

Вы не можете изменить Список , пока вы повторяете его, как в первом примере. Во втором у вас просто обычный цикл для .

0
ответ дан 3 December 2019 в 21:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: