foreach循环中的ConcurrentModificationException

时间:2014-02-06 19:30:29

标签: java collections arraylist concurrentmodification

在我的代码中:

    Collection<String> c = new ArrayList<>();
    Iterator<String> it = c.iterator();
    c.add("Hello");
    System.out.println(it.next());

发生异常,因为我的集合在迭代器创建后发生了变化。

但是在这段代码中呢:

 ArrayList<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);
    for (Integer integer : list) {     // Exception is here
        if (integer.equals(2)) {
            list.remove(integer);
        }
    }

为什么发生异常?

在第二段代码中,我在for-each循环之前对我的集合进行了更改。

5 个答案:

答案 0 :(得分:5)

在第二个循环中,原因相同 - 您要从列表中删除元素。

要在循环中删除List中的元素,请使用标准的老式for循环:

for(int i=0;i<list.size();i++) {

并删除该循环中的列表项或使用ListIterator迭代列表。

答案 1 :(得分:1)

您也在for-each循环中更改您的集合:

  list.remove(integer);

如果您需要在迭代时删除元素,您可以跟踪需要删除的索引并在for-each循环结束后删除它们,或者使用允许并发修改的Collection。

答案 2 :(得分:1)

异常是因为您正在迭代以及从列表中删除元素

 for (Integer integer : list) {     // Exception is here because you are iterating and also removing the elements of same list here
        if (integer.equals(2)) {
            list.remove(integer);
        }

答案 3 :(得分:0)

如果您需要在使用更好的语法进行迭代时删除元素,这是最简单的永远不会获得ConcurrentModificationExceptions的方法:

// utility method somewhere
public static < T > Iterable< T > remainingIn( final Iterator< T > itT ) {
    return new Iterable< T >() {
        @Override
        public Iterator< T > iterator() {
            return itT;
        }
    }
}

// usage example
Iterator< Integer > itI = list.iterator();
for ( Integer integer : remainingIn( itI ) ) {
    if ( integer.equals( 2 ) ) {
        itI.remove();
    }
}

答案 4 :(得分:0)

您可以改为使用CopyOnWriteArrayList,它效率不高,但解决了ConcurrentModificationException,您可以安全地使用remove方法。