list中for循环删除多个元素为何报错?

423 阅读2分钟

干货点:最近review同事代码的时候发现了一个问题,在ArrayList中边遍历边删除多个元素,在提醒同事后就想着写篇文章从源码角度详细聊聊这个问题好了,当然了我也发现很多人其实都不知道这个报错的原理是什么,如果你也不知道,那确实该好好看这篇文章了。

前几天review同事代码的时候发现对方提交了一份list中边遍历边删除的代码,大概是这样的:

1.png

初学者咋一看其实没毛病,可是运行结果会是这样的:

2.png

哦豁,这是为啥?大家都知道,本饭遇见问题喜欢刨根问底,于是我就在报错的地方断个点,可以看到,在第一次遍历的时候

3.png

两个值都是6相等,因此不会抛出ConcurrentModificationException异常。而等到i==2被移除后

4.png

可以看到两个值并不一样,因此抛出出ConcurrentModificationException异常终止程序。

本着刨根问底的心态,自然下一步要解决的就是这两个值是什么时候被设置进来以及为什么会不一样呢?

本饭反断点了回去看到在加到第6个值的时候

5.png

可以看到此时的modCount为6,到了这一步就解决了ArrayList.this.modCount的设置问题了, 接下来看下上文提到的this.expectedModCount问题,我断点for循环后深入调试可以看到

6.png

此处在取得遍历器的时候就已经将ArrayList.this.modCount赋值到expectedModCount中,到了这一步就很明显了,在进行remove(i)的时候改变了ArrayList.this.modCount的值,导致两个值不相同,后面还有元素再进行遍历的时候check了一下,发现不对等,所以才翻了车,哦,不对,才报的错。

嗯,终于描述完这个过程了,那么我们再看看,这样子会有问题吗

7.png

不会的,哈哈哈,因为在你remove掉数据后,便直接return掉了,不会再进行后续的check,那么自然也就没有问题了。

那么难道就没有方法可以一边遍历一边进行多次删除了吗,不是的,详情等我下篇文章,敬请期待!!!

logo