#java #arraylist #collections #concurrentmodification
Вопрос:
package com.ripal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
public class Outputs {
public void show() {
final ArrayList<String> list = new ArrayList<String>();
list.add("banana");
list.add("apple");
Iterator<String> itr = list.iterator();
Collections.sort(list);
while (itr.hasNext()) {
System.out.println(itr.next() " ");
}
}
}
class Test {
public static void main(String[] args) {
Outputs outputs = new Outputs();
outputs.show();
}
}
Ответ №1:
ArrayList
имеет быстрый итератор сбоев. Вы можете изменять коллекцию только с помощью итератора. Любая другая модификация, выполненная снаружи, обнаруживается раньше после вызова методов итератора и ConcurrentModificationException
генерируется a . В вашем случае после создания итератора вы сортируете массив на месте, и эта процедура сортировки изменяет содержимое массива, ConcurrentModificationException
что приводит к использованию итератора. Чтобы устранить проблему, просто выполните сортировку перед созданием итератора. Вот как это выглядит.
Collections.sort(list);
Iterator<String> itr = list.iterator();
Комментарии:
1. Альтернатива состоит в том, чтобы не иметь дело с итераторами, когда в этом нет необходимости:
for(String s: list) System.out.println(s);
(Пустое пространство в конце строки в любом случае бессмысленно, альтернативой былоSystem.out.println(String.join(" ", list));
бы, если бы это было фактическое намерение).2. Что интересно в этом, так это то, что в документации ArrayList говорится, что CME генерируется, если вы структурно изменяете список; но сортировка ArrayList не является структурной модификацией (это просто перемещение элементов в массиве) (например, вы можете отсортировать список, который нельзя структурно изменить,
Arrays.asList
). Но исходный код явно обновляет modCount .3. Похоже
replaceAll
, аналогично обновляет modCount без структурных изменений.