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

Этот вопрос уже имеет ответ здесь:

У меня есть следующая часть кода:

private String toString(List 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, кто-либо может объяснить, почему это происходит, даже если код работает в том же потоке? И как я мог избежать его?

79
задан Olimpiu POP 18 February 2014 в 14:08
поделиться

4 ответа

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

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();
    }
}
162
ответ дан 24 November 2019 в 10:05
поделиться

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

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

8
ответ дан 24 November 2019 в 10:05
поделиться

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

Iterator<Item> iter = list.iterator();
while(iter.hasNext()) {
  Item blah = iter.next();
  if(...) {
    iter.remove(); // Removes the 'current' item
  }
}
25
ответ дан 24 November 2019 в 10:05
поделиться

Выполняя итерацию цикла, вы пытаетесь изменить значение списка в операции remove (). Это приведет к исключению ConcurrentModificationException.

Следуйте приведенному ниже коду, который достигнет того, чего вы хотите, но при этом не вызовет никаких исключений.

private String toString(List aDrugStrengthList) {
        StringBuilder str = new StringBuilder();
    List removalList = new ArrayList();
    for (DrugStrength aDrugStrength : aDrugStrengthList) {
        if (!aDrugStrength.isValidDrugDescription()) {
            removalList.add(aDrugStrength);
        }
    }
    aDrugStrengthList.removeAll(removalList);
    str.append(aDrugStrengthList);
    if (str.indexOf("]") != -1) {
        str.insert(str.lastIndexOf("]"), "\n          " );
    }
    return str.toString();
}
6
ответ дан 24 November 2019 в 10:05
поделиться
Другие вопросы по тегам:

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