Java中遍历ArrayList的过程中删除元素操作会发生并发修改异常?

ArrayListal=newArrayList();al.add("1");al.add("2");al.add("3");al.add("4");al.add("xx... ArrayList al=new ArrayList();
al.add("1");
al.add("2");
al.add("3");
al.add("4");
al.add("xxx");
al.add("n-1");
al.add("n");
for(Object o:al){
if("x".equals(o)){
al.remove(o);
}
}
我发现了一个规律,就是只有x=n-1的时候不会发生任何异常,其余情况下都会发生并发修改异常?为什么,为什么“x=n-1的时候不会发生任何异常”
展开
 我来答
out1miss
推荐于2017-09-01
知道答主
回答量:15
采纳率:0%
帮助的人:11.5万
展开全部

首先搞清楚不是x=n-1不报错。是因为他避开了错误,实际当你用倒数第2个来删除的时候,他就已经跳出循环,不会判断最后以为,这是为什么呢?

我们先看看加强for循环是怎么实现的。都知道是通过迭代实现,那么将for写成迭代器来看。

        Iterator<Object> itr = al.iterator();
            while(itr.hasNext()){
                Object o = itr.next();
                System.out.println(itr.hasNext());
                if("n" .equals(o)){
                al.remove(o);
            }
        }

以上就是加强for循环的真正样子。再来透析源代码。

al.iterator():返回一个迭代器没什么好说的;

itr.hasNext():通过判断 cursor(游标) != size(长度)来决定是否结束循环,cursor(游标) 初始是0 每次经过 itr.next() +1;当cursor==size时 会跳出循环,这也是为什么倒数第2个不会出错的主要原因; 

itr.next(): 看源代码可以发现每次在next()调用后,都会先调用checkForComodification()这个方法;

checkForComodification(): 主要作用是判断itr迭代器数据是否和list一致,

有两个参数,

第一个 modCount 集合结构变动次数,如:一开始你add调用了7次,那么这个数就是7,

第二个 expectedModCount 在调用iterator()方法时,初始化值等于modCount ,

这个方法判断当 modCount != expectedModCount 时

抛出异常ConcurrentModificationException,如果你调用迭代器的remove方法,expectedModCount 会重新赋值,但是你调用的是list的remove方法,那么modCount 就会+1 而expectedModCount 不变,这就会造成 modCount != expectedModCount;

最后,看看为什么倒数第2个不会抛异常:

当他遍历到“n-1”时,cursor=6,然后调用remover(o)方法,size=6,这个时候调用了itr.hasNext()判断 cursor是否等于size,前面说过,当cursor==size时,跳出循环,那么就不会进入next(),也就不会进入checkForComodification()方法,所以不会抛出异常,说白了,也就是循环次数少了一次。

结合着源码看,应该会比较清晰。

白菜一颗
2015-06-23 · TA获得超过8916个赞
知道大有可为答主
回答量:3260
采纳率:69%
帮助的人:3705万
展开全部
ArrayList 循环删除的时候需要从后往前删,因为删了之后会把后面的所有元素向前移动,而最后空出来的那个会成为 null ,所以当你从前往后删的时候前面删除了后面补上,循环到后面的时候就有一部分成 null 了就报错了
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式