什么?ArrayList我用增强for循环删除居然没报错?

编程入门 行业动态 更新时间:2024-10-25 22:35:02

什么?ArrayList<a href=https://www.elefans.com/category/jswz/34/1770151.html style=我用增强for循环删除居然没报错?"/>

什么?ArrayList我用增强for循环删除居然没报错?

笔者在阅读阿里巴巴Java开发手册时看到这样一段话:

不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用Iterator 方式,如果并发操作,需要对 Iterator 对象加锁
正例:

List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {String item = iterator.next();if (删除元素的条件) {iterator.remove();}
}

反例:

for (String item : list) {if ("1".equals(item)) {list.remove(item);}
}

说明:以上代码的执行结果肯定会出乎大家的意料,那么试一下把“1”换成“2”,会是同样的结果吗?

笔者疑惑,什么意思,难道不是所有的增强for删除元素都会报错吗?记得是modCount != expectedModCount的时候会报错呀

于是笔者实现了一下,发现…

        List<String> list = new ArrayList<>();list.add("1");list.add("2");for (String item : list) {if ("1".equals(item)) {list.remove(item);}}System.out.println(list);

发现居然…

一条小绿条震惊了我

然后我执行第二套代码,也就是把1换成2

        List<String> list = new ArrayList<>();list.add("1");list.add("2");for (String item : list) {if ("2".equals(item)) {list.remove(item);}}System.out.println(list);


呼~报错了,是我满意的结果。

于是,我决定debug一下发生了什么,第一套代码为什么不会报错呢。

首先进到remove方法

很合理,进到fastRemove方法了

modCount++,移动元素,让空出的位置值null让GC清理,很合理,1 被删除了。

然后回来,return true,进行下一个遍历。增强for是会用ArrayList的内部类,来判断是否有下一个元素,cursor是一个游标,判断是否遍历到头了。
可以看到,由于刚才已经删除了“1”,所以size为1,而cursor由于是到索引1了,haxNext的判断游标与长度是相等的,在他看来遍历结束了,返回false。于是遍历结束,这样还没进入到modCount和expectedModCount的比较,遍历就已经退出~

让我们再来看看第二套代码

由于第一个值是“1”,不相等,所以直接进入第二个循环


跟前面一样,会用ArrayList的内部类判断是否遍历结束

这里游标为1,size为2,所以不相等,为true

接下来是调用next方法,这个方法依旧是ArrayList的内部类Itr持有

进入checkForComodification方法

可以看到,由于之前没有删除操作,所以这一步是ok的,不会报错。

继续走next剩余的方法,没有问题。

接下来因为相等了,执行remove方法

执行fastRemove方法,modCount的值变化

然后增强for循环继续

发现hasNext依旧成立,因为游标cursor为2,而长度为1
于是执行next方法,首先执行checkForComodification

modCount不等于expectedModCount,抛出异常

总结:
原来如此,代码1之所以没有报错,原来是因为它没有进入到modCount和expectedModCount的判断就结束了。但是只要我们明确不能在增强for循环删除、插入元素,还是ok的~。

果然,要了解底层,还是得自己看看源码才知道。

更多推荐

什么?ArrayList我用增强for循环删除居然没报错?

本文发布于:2024-03-23 22:14:50,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1743466.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:我用   报错   ArrayList

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!