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