Вопрос-ответ

ConcurrentModificationException for ArrayList [duplicate]

ConcurrentModificationException для ArrayList [дубликат]

У меня есть следующий фрагмент кода:

private String toString(List<DrugStrength> aDrugStrengthList) {
StringBuilder str = new StringBuilder();
for (DrugStrength aDrugStrength : aDrugStrengthList) {
if (!aDrugStrength.isValidDrugDescription()) {
aDrugStrengthList.remove(aDrugStrength);
}
}
str.append(aDrugStrengthList);
if (str.indexOf("]") != -1) {
str.insert(str.lastIndexOf("]"), "\n " );
}
return str.toString();
}

Когда я пытаюсь запустить его, я получаю ConcurrentModificationException, кто-нибудь может объяснить, почему это происходит, даже если код выполняется в том же потоке? И как я мог этого избежать?

Переведено автоматически
Ответ 1

Вы не можете удалить из списка, если просматриваете его с помощью цикла "для каждого". Вы можете использовать Iterator. Заменить:

for (DrugStrength aDrugStrength : aDrugStrengthList) {
if (!aDrugStrength.isValidDrugDescription()) {
aDrugStrengthList.remove(aDrugStrength);
}
}

С:

for (Iterator<DrugStrength> it = aDrugStrengthList.iterator(); it.hasNext(); ) {
DrugStrength aDrugStrength = it.next();
if (!aDrugStrength.isValidDrugDescription()) {
it.remove();
}
}
Ответ 2

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

Iterator<Item> iter = list.iterator();
while(iter.hasNext()) {
Item blah = iter.next();
if(...) {
iter.remove(); // Removes the 'current' item
}
}
Ответ 3

Мне нравится обратный порядок для цикла, такой как:

int size = list.size();
for (int i = size - 1; i >= 0; i--) {
if(remove){
list.remove(i);
}
}

потому что это не требует изучения каких-либо новых структур данных или классов.

Ответ 4

должна быть параллельная реализация интерфейса списка, поддерживающего такую операцию.

попробуйте java.util.concurrent.CopyOnWriteArrayList.class

java collections concurrency