@java李杨勇、@墨理学AI,新的一天,来一起学习在开发中最常遇到的问题吧!

二、使用增强for循环删除元素,猜猜下面代码会输出什么?

List<String> list = new ArrayList<>();
list.add("淘宝");
list.add("淘宝");
list.add("掘金");
for(String item : list) {
if("淘宝".equals(item)) {
list.remove(item);
}
}

解答:直接抛出ConcurrentModificationException异常,其实增强for循环只是一个语法糖,方便开发者使用,在虚拟机实际的被执行的时候是通过迭代器的方式循环,对上面的代码进行反编译得到如下代码:【图1】

为什么使用迭代器循环方式在循环的时候删除元素会抛出这个异常呢?实际上,迭代器在每次调用next()方法的时候,第一步就会先去执行checkForComodification()方法,这个方法的目的就是检查list下的modCount是否和expectedModCount变量的值一致(可以理解为版本号),如果不一致,则直接抛出ConcurrentModificationException异常。

删除的流程是这样的呢?实际上modCount变量表示的含义是集合被修改的次数,每次对集合进行add或者remove的时候,则会对它进行+1,在调用集合的remove方法时,该变量的值会被加1,但是expectedModCount的值却没有变动,此时,当再次执行next方法时判断则两者值不相等,于是抛出异常。【图2】

解决方案:使用迭代器的remove方法,即将上面删除的代码修改为: iterator.remove(),在迭代器的remove方法中,会将modCount的值赋值给expectedModCount,所以在下次执行next方法的时候,两者的值还是一样的,就不会抛出异常。

因为沸点字数有限制,更多原因请看:【图3】分析
展开
IT学习日记v于2022-01-18 00:15发布的图片
IT学习日记v于2022-01-18 00:15发布的图片
IT学习日记v于2022-01-18 00:15发布的图片
1