ArrayList的ConcurrentModificationException

mab*_*zer 79 java collections concurrency

我有以下代码:

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();
}
Run Code Online (Sandbox Code Playgroud)

当我尝试运行它时,我得到ConcurrentModificationException,任何人都可以解释它为什么会发生,即使代码在同一个线程中运行?我怎么能避免它呢?

Kon*_*rus 162

如果您使用"for each"循环浏览它,则无法从列表中删除.你可以用Iterator.更换:

for (DrugStrength aDrugStrength : aDrugStrengthList) {
    if (!aDrugStrength.isValidDrugDescription()) {
        aDrugStrengthList.remove(aDrugStrength);
    }
}
Run Code Online (Sandbox Code Playgroud)

附:

for (Iterator<DrugStrength> it = aDrugStrengthList.iterator(); it.hasNext(); ) {
    DrugStrength aDrugStrength = it.next();
    if (!aDrugStrength.isValidDrugDescription()) {
        it.remove();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不知道谢谢你@KonradGarus (2认同)

Edw*_*ale 25

与其他答案一样,您无法从正在迭代的集合中删除项目.您可以通过显式使用Iterator和删除项目来解决这个问题.

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


小智 16

我喜欢循环的逆序,例如:

int size = list.size();
for (int i = size - 1; i >= 0; i--) {
    if(remove){
        list.remove(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

因为它不需要学习任何新的数据结构或类.


小智 8

应该有一个支持这种操作的List接口的并发实现.

尝试java.util.concurrent.CopyOnWriteArrayList.class


bra*_*boy 6

在迭代循环时,您尝试在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();
}
Run Code Online (Sandbox Code Playgroud)