失败的快速迭代器实现

时间:2013-10-08 20:31:21

标签: java iterator

有类似的问题,但不完全是我想问的问题。 我想问一下Iterator如何检查修改。

This link表示它的实现存在于AbstractList类中,其中定义了一个int变量modCount,它提供了列表大小已更改的次数。在每次next()调用中使用此值来检查函数checkForComodification()中的任何修改。

但我真的不明白。如果仅在每次下一次调用后检查该值,那么如果我执行删除,然后添加相同的调用,则大小不会更改,并且modCount也不应更改。但删除和添加相同的循环迭代也会抛出异常。

2 个答案:

答案 0 :(得分:8)

如果您查看Collection实施的代码,请选择ArrayList;我们在modCount中声明了AbstractList变量:

protected transient int modCount = 0;

然后在我们拥有的remove的每个修改方法(例如ArrayList)中

public E remove(int index) {
    rangeCheck(index);

    modCount++;
    //....

所以modCount只是递增; 从不递减。

Iterator我们有:

final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}

其中expectedModCountmodCount创建Iterator时的快照。

因此,如果在List的同一个实例正在使用时,对基础Iterator进行任何修改,则会抛出ConcurrentModificationException。< / p>

我认为有一个极端情况,如果你进行了足够的修改,那么int会溢出并再次返回原始值 - 这将是一个相当大的数字或修改然而;确切地说,2 32

答案 1 :(得分:6)

修改列表时

modCount总是增加(因此 mod 计数),所以当删除时它也应该增加。 因此,删除和添加调用都会增加。

正如鲍里斯蜘蛛所说,modCount溢出的角落情况,你可以这样做:

List<Integer> nums = new ArrayList<>();
for(int i = 0; i < 10; i++) nums.add(i);
for(int n : nums) {
    System.out.println(n);
    for(int i = -1; i < Integer.MAX_VALUE; i++) {
        nums.add(i);
        nums.remove(nums.size() - 1);
    }
}

将(慢慢地)打印0到9而不会抛出任何异常。