为什么不会抛出ConcurrentModificationException?

时间:2017-07-29 08:18:17

标签: java iterator concurrentmodification fail-fast

看看这段代码:

ArrayList al = new ArrayList();
al.add("AA");
al.add("AB");
al.add("AC");
Iterator it = al.iterator();
while(it.hasNext()){
String s = (String)it.next();
if(s.equals("AB")){
al.remove(1);
}
}

由于ArrayList具有故障快速迭代器,显然,给定的ArrayList不是由固定大小的数组组成的(会使remove()方法无法使用< / em>),上面的代码应该抛出ConcurrentModificationException,但是,它没有。{/ p>

另外,如果我在循环中插入一个print语句(作为第一个语句),它会显示循环不会第三次迭代并且它会正常退出。

我知道这听起来太愚蠢但是我能想到 falsely 的唯一原因是,元素的移除元素被遍历之后发生了迭代器。但事实并非如此,因为modificationCount仍然被删除修改,所以它必须抛出异常。

刚做

while(it.hasNext()){
it.next();
al.remove(1);
}

会抛出ConcurrentModificationException。

任何见解?

2 个答案:

答案 0 :(得分:2)

这是因为hasNext()方法未检查modCount

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

因此,在调用remove(1)之后,列表的大小将与光标一样为2,hasNext()将返回false。永远不会调用next()方法,永远不会检查modCount

如果在迭代之前向列表中添加第四个元素,则会得到与第二个示例类似的异常。

答案 1 :(得分:0)

并发修改检查仅在Iterator的next()来电期间进行,但未在hasNext() {{}}}中解释。{/ 3}}。

Bubletan's answer清楚地指明了

  

失败快速迭代器抛出一个ConcurrentModificationException   尽力而为的基础。因此,编写程序是错误的   这取决于它的正确性:快速失败   迭代器的行为应仅用于检测错误。

因此,在迭代过程中修改集合是一种错误的编程习惯。