我有以下代码:
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
,有人可以解释它为什么会发生,即使代码在同一个线程中运行吗?我怎么能避免它?
答案 0 :(得分:154)
如果您使用“for each”循环浏览它,则无法从列表中删除。您可以使用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();
}
}
答案 1 :(得分:24)
与其他答案一样,您无法从正在迭代的集合中删除项目。你可以通过明确使用Iterator
并删除那里的项目来解决这个问题。
Iterator<Item> iter = list.iterator();
while(iter.hasNext()) {
Item blah = iter.next();
if(...) {
iter.remove(); // Removes the 'current' item
}
}
答案 2 :(得分:14)
我喜欢循环的逆序,例如:
int size = list.size();
for (int i = size - 1; i >= 0; i--) {
if(remove){
list.remove(i);
}
}
因为它不需要学习任何新的数据结构或类。
答案 3 :(得分:7)
应该有一个支持这种操作的List接口的并发实现。
尝试java.util.concurrent.CopyOnWriteArrayList.class
答案 4 :(得分:5)
在遍历循环时,您尝试在remove()操作中更改List值。这将导致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();
}
答案 5 :(得分:2)
我们可以使用并发集合类来避免在迭代集合时出现ConcurrentModificationException,例如CopyOnWriteArrayList而不是ArrayList。
查看ConcurrentHashMap的这篇文章
http://www.journaldev.com/122/hashmap-vs-concurrenthashmap-%E2%80%93-example-and-exploring-iterator