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

631   6  

6 ответов:

вы не можете удалить из списка, если вы просматриваете его с помощью "для каждого" цикла. Вы можете использовать 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();
    }
}

Iterator и удаление элемента там.

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

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

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

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

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

попробуйте java.утиль.параллельный.CopyOnWriteArrayList.класс

при повторении цикла вы пытаетесь изменить значение списка в операции 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();
}

мы можем использовать параллельные классы коллекции, чтобы избежать ConcurrentModificationException при итерации по коллекции, например CopyOnWriteArrayList вместо ArrayList.

проверьте этот пост для ConcurrentHashMap

http://www.journaldev.com/122/hashmap-vs-concurrenthashmap-%E2%80%93-example-and-exploring-iterator

Comments

    Ничего не найдено.