java.util.ConcurrentModificationException

问题:

注意:我知道Iterator#remove()方法。
在下面的代码示例中,我不明白为什么main方法List.removeremove方法中抛出ConcurrentModificationException

public class RemoveListElementDemo {    
    private static final List<Integer> integerList;

    static {
        integerList = new ArrayList<Integer>();
        integerList.add(1);
        integerList.add(2);
        integerList.add(3);
    }

    public static void remove(Integer toRemove) {
        for(Integer integer : integerList) {
            if(integer.equals(toRemove)) {                
                integerList.remove(integer);
            }
        }
    }

    public static void main(String... args) {                
        remove(Integer.valueOf(2));

        Integer toRemove = Integer.valueOf(3);
        for(Integer integer : integerList) {
            if(integer.equals(toRemove)) {                
                integerList.remove(integer);
            }
        }
    }
}

回答:

这就是为什么:
正如Javadoc所说:

这个类的迭代器和listIterator方法返回的迭代器是故障快速的:如果列表在迭代器创建之后的任何时间被结构化地修改,除了通过迭代器自己的remove或add方法之外,迭代器将抛出一个ConcurrentModificationException。

这个检查是在迭代器的next()方法中完成的(正如你可以看到的stacktrace)。但是,只有在hasNext()传递真实的情况下,我们才能达到next()方法,这是每个方法调用的,以检查边界是否满足。在你的删除方法中,当hasNext()检查是否需要返回另一个元素时,它会看到它返回两个元素,现在在删除一个元素之后,列表只包含两个元素。所以都是桃子,我们完成了迭代。并发修改的检查不会发生,因为这样做是在next()方法中完成的,该方法从未被调用。
接下来我们到第二个循环。在我们删除第二个数字之后,hasNext方法将再次检查是否可以返回更多的值。它已经返回了两个值,但是列表现在只包含一个。但这里的代码是:

public boolean hasNext() {
        return cursor != size();
}

1!= 2,所以我们继续使用next()方法,现在意识到某人已经搞砸了列表并触发了异常。
希望清除你的问题。

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: java.util.ConcurrentModificationException

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

11 − 1 =