当我尝试删除元素时,为什么这个ArrayList会抛出ConcurrentModificationException?

时间:2012-02-27 17:17:19

标签: java collections concurrency iterator

我正在尝试从Arraylist中删除一个特定元素,它会抛出一个ConcurrentModificationException

ArrayList<String> ar = new ArrayList<String>();
ar.add("a");
ar.add("b");
ar.add("c");
ar.add("a");
ar.add("e");
for(String st: ar){
    System.out.println("st="+st);
    if(st.equals("a")){
        ar.remove(st);
    }
}

任何评论,我做错了什么?

3 个答案:

答案 0 :(得分:4)

在使用Iterator.remove()进行迭代时,仅从数组中删除元素。

for(String st: ar) {行有点误导。您实际上是在幕后创建一个迭代器,用于此迭代。如果需要从迭代中删除元素,则需要显式使用迭代器,以便可以调用iterator.remove()

ArrayList<String> ar = new ArrayList<String>();
ar.add("a");
ar.add("b");
ar.add("c");
ar.add("a");
ar.add("e");
Iterator<String> it = ar.iterator();
while (it.hasNext()) {
    String st = it.next();
    System.out.println("st="+st);
    if (st.equals("a")) {
        it.remove();
    }
}

答案 1 :(得分:0)

当您迭代该集合时,您正在从集合中删除元素,而不使用迭代器来执行此操作。不要那样做。有很多选择,主要是:

  • 改为使用索引(getremoveAt)小心您的计数,这样就不会跳过项目

     for (int i = 0; i < ar.size(); i++) {
         String st = ar.get(i);
         System.out.println("st="+st);
         if(st.equals("a")) {
             ar.removeAt(i);
             i--; // We want to use this index again
         }
     }
    
  • 构建要删除的项目集合,然后将其全部删除

    List<String> elementsToRemove = new ArrayList<String>();
    for(String st: ar){
        System.out.println("st="+st);
        if(st.equals("a")){
            elementsToRemove.add(st);
        }
    }
    ar.removeAll(elementsToRemove);
    
  • 使用迭代器删除,如果迭代器支持删除(如ArrayList那样)

    for (Iterator<String> it = ar.iterator(); it.hasNext(); ) {
        String st = it.next();
        System.out.println("st="+st);
        if(st.equals("a")) {
            it.remove();
        }
    }
    

答案 2 :(得分:0)

您正在修改正在迭代的数组。 我建议你使用Iterator做类似的事情。