代码之家  ›  专栏  ›  技术社区  ›  mabuzer

ArrayList[duplicate]的ConcurrentModificationException

  •  77
  • mabuzer  · 技术社区  · 15 年前

    我有以下代码:

    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 回复  |  直到 11 年前
        1
  •  171
  •   Konrad Garus    15 年前

    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();
        }
    }
    
        2
  •  27
  •   Edward Dale    15 年前

    正如其他答案所说,您不能从正在迭代的集合中移除项。可以通过显式使用 Iterator 把那个东西拿走。

    Iterator<Item> iter = list.iterator();
    while(iter.hasNext()) {
      Item blah = iter.next();
      if(...) {
        iter.remove(); // Removes the 'current' item
      }
    }
    
        3
  •  21
  •   froman    12 年前

    我喜欢循环的相反顺序,例如:

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

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

        4
  •  8
  •   idiotgenius    15 年前

    应该有一个支持这种操作的列表接口的并发实现。

    请尝试java.util.concurrent.CopyOnWriteArrayList.class

        5
  •  6
  •   bragboy    9 年前

    在循环中迭代时,您正在尝试更改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
  •  3
  •   Suganthan Madhavan Pillai    11 年前

    我们可以使用并发集合类来避免在对集合进行迭代时出现ConcurrentModificationException,例如CopyOnWriteArrayList而不是ArrayList。

    请查看此帖子中的ConcurrentHashMap

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