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

正例: Iterator<String> iterator = list.iterator();

while (iterator.hasNext()) {

String item = iterator.next();

if (删除元素的条件) {

iterator.remove();

}

}

反例: List<String> list = new ArrayList<String>();

list.add("1");

list.add("2");

for (String item : list) {

if ("1".equals(item)) {

list.remove(item);

}

}

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

根本原因在于expectedModCount与modCount他们的不相等,由于执行了ArrayList中的remove(),modCount在每一次循环值会发生改变,而expectedModCount并没有发生,在执行checkForComodification()方法就会抛出异常。

如下代码:

编译器编译后的代码如下:

}

首先大家应该了解,对集合做remove,and等操作会触修改次数(modCount)的增加。

以下是集合实现的Iterator.hasNext()方法

cursor:下一个元素的索引位置(调用Interator.next()是会触发cursor+1)

size:集合长度

总结:如果我们我们用foreach删除的元素刚好是最后一个,删除完成前cursor刚好等于size的大小。但是,删除完成后size的数量减1,但是cursor并没有变化。导致下一次循环不相等继续向下执行,导致检查数组不通过,抛出java.util.ConcurrentModificationException

为什么使用下面的方法就不会出现这种情况:

请看箭头所指处:

foreach是直接调用集合的删除方法,而上面是调用iterator的删除方法:

相信大家一看便知!

1.首先检查集合

2.删除元素

3.cursor重新赋值

4.检查集合参数重新赋值

---------------------
作者:这个人好帅
来源:CSDN
原文:https://blog.csdn.net/weixin_39032575/article/details/80724984
版权声明:本文为博主原创文章,转载请附上博文链接!

不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁的更多相关文章

  1. foreach循环里不能remove/add元素的原理

    foreach循环 ​    foreach循环(Foreach loop)是计算机编程语言中的一种控制流程语句,通常用来循环遍历数组或集合中的元素.Java语言从JDK 1.5.0开始引入forea ...

  2. 为什么阿里巴巴Java开发手册中强制要求不要在foreach循环里进行元素的remove和add操作?

    在阅读<阿里巴巴Java开发手册>时,发现有一条关于在 foreach 循环里进行元素的 remove/add 操作的规约,具体内容如下: 错误演示 我们首先在 IDEA 中编写一个在 f ...

  3. 为什么阿里巴巴禁止在 foreach 循环里进行元素的 remove/add 操作--java.util.ConcurrentModificationException

    摘要 foreach循环(Foreach loop)是计算机编程语言中的一种控制流程语句,通常用来循环遍历数组或集合中的元素. 在阿里巴巴Java开发手册中,有这样一条规定: 但是手册中并没有给出具体 ...

  4. 为什么禁止在 foreach 循环里进行元素的 remove/add 操作

    首先看下边一个例子,展示了正确的做法和错误的错发: 这是为什么呢,具体原因下面进行详细说明: 1.foreach循环(Foreach loop)是计算机编程语言中的一种控制流程语句,通常用来循环遍历数 ...

  5. 有关集合的foreach循环里的add/remove

    转自:Hollis(微信号:hollischuang) 在阿里巴巴Java开发手册中,有这样一条规定: 但是手册中并没有给出具体原因,本文就来深入分析一下该规定背后的思考. 1 .foreach循环 ...

  6. JSTL中c:forEach循环里的值的substr操作及对String操作的常用API

    <c:forEach items="${dataList}" var="item" varStatus="itemStatus"> ...

  7. IT兄弟连 Java语法教程 数组 使用foreach循环遍历数组元素

    从JDK5之后,Java提供了一种更简单的循环:foreach循环,也叫作增强for循环,这种循环遍历数组和集合更加简洁.使用foreach循环遍历数组和集合元素时,无需获得数组或集合的长度,无需根据 ...

  8. 禁止foreach循环使用remove/add----快速失败

    阿里巴巴开发手册中有一条: 7[强制]不要在 foreach 循环里进行元素的 remove / add 操作. remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterato ...

  9. [置顶] java的foreach循环

    foreach语句是java5之后的新特征之一,在循环遍历数组.集合方面更加简洁. 使用foreach循环遍历数组和集合时,无需获得数组和集合的长度,无须根据索引来访问数组元素和集合元素,foreac ...

随机推荐

  1. Springboot2.x 启动报错:Bean named 'xxxService'... but was actually of type 'com.sun.proxy.$Proxy82'

    Springboot 2.0.5 搭建一个新项目启动后报错:Bean named 'xxxService'... but was actually of type 'com.sun.proxy.$Pr ...

  2. mongodb 索引,全文索引与唯一索引

    唯一索引创建: db.createIndex({name: 1}, {unique: true})

  3. C++学习笔记52:查找

    //函数查找 template <class T> int seqSearch(const T list[], int n, const T &key) { ; i < n; ...

  4. Linux下安装配置virtualenv与virtualenvwrapper

    一.Linux下安装.配置virtualenv 配置源 #指定清华源下载pip的包 [root@localhost opt]# pip3 install -i https://pypi.tuna.ts ...

  5. Python高级有关的题目

    1,copy模块 from copy import deepcopy dic = {} list = [] for i in range(10): dic["num"] = i i ...

  6. 小甲鱼python第二讲课后习题

    0.什么是BIF BIF为内置函数,英语全称为Build-in-Function Python3用input()取代了Python2的raw_input(),接收用户输入 1.用课堂上小甲鱼教的方法数 ...

  7. Sublime_SublimeServer

    1. 遇到问题:如下代码第17行,获取本地json文件,如果直接在浏览器中打开引用该文件的.html文件,在chrme浏览器中并不能读取到json文件. var vm=new Vue({ el:&qu ...

  8. spring中的多线程aop方法拦截

    日常开发中,常用spring的aop机制来拦截方法,记点日志.执行结果.方法执行时间啥的,很是方便,比如下面这样:(以spring-boot项目为例) 一.先定义一个Aspect import org ...

  9. .NET的前世今生与将来

    笔者注 谨以此文纪念我敬重的2016年9月17日去世的 装配脑袋 逝世两周年 让大家久等了,前后花了1年的时间,几经改版,终于完成撰写了一万字长文,回顾和展望.NET这16年来的成功与失败.最终能成文 ...

  10. numpy.trace对于三维以上array的解析

    numpy.trace是求shape的对角线上的元素的和,具体看 https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.t ...