首先,这涉及多线程操作,Iterator是不支持多线程操作的,List类会在内部维护一个modCount的变量,用来记录修改次数

举例:ArrayList源码

protected transient int modCount = 0;

每生成一个Iterator,Iterator就会记录该modCount,每次调用next()方法就会将该记录与外部类List的modCount进行对比,发现不相等就会抛出多线程编辑异常。

为什么这么做呢?我的理解是你创建了一个迭代器,该迭代器和要遍历的集合的内容是紧耦合的,意思就是这个迭代器对应的集合内容就是当前的内容,我肯定不会希望在我冒泡排序的时候,还有线程在向我的集合里插入数据对吧?所以Java用了这种简单的处理机制来禁止遍历时修改集合。

至于为什么删除“1”就可以呢,原因在于foreach和迭代器的hasNext()方法,foreach这个语法糖,实际上就是

while(itr.hasNext()){

itr.next()

}

所以每次循环都会先执行hasNext(),那么看看ArrayList的hasNext()是怎么写的:

public boolean hasNext() {

return cursor != size;

}

cursor是用于标记迭代器位置的变量,该变量由0开始,每次调用next执行+1操作,于是:

你的代码在执行删除“1”后,size=1,cursor=1,此时hasNext()返回false,结束循环,因此你的迭代器并没有调用next查找第二个元素,也就无从检测modCount了,因此也不会出现多线程修改异常

但当你删除“2”时,迭代器调用了两次next,此时size=1,cursor=2,hasNext()返回true,于是迭代器傻乎乎的就又去调用了一次next(),因此也引发了modCount不相等,抛出多线程修改的异常。

当你的集合有三个元素的时候,你就会神奇的发现,删除“1”是会抛出异常的,但删除“2”就没有问题了,究其原因,和上面的程序执行顺序是一致的。

java foreach 删除_为什么java不要在foreach循环里进行元素的remove/add操作相关推荐

  1. 不要在 foreach 循环里进行元素的 remove / add 操作

    在foreach 循环里面,不能用remove方法,因为当list里面的最后一个元素被remove时候,会报错. 摘自<阿里巴巴Java开发手册> [强制]不要在 foreach 循环里进 ...

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

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

  3. 【Java开发规范】禁止在 foreach 循环里进行元素的 remove/add 操作

    在阿里巴巴Java开发手册中,有这样一条规定: 但是手册中并没有给出具体原因,本文就来深入分析一下该规定背后的思考. foreach循环 Foreach循环(Foreach loop)是计算机编程语言 ...

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

    在阿里巴巴Java开发手册中,有这样一条规定: 但是手册中并没有给出具体原因,本文就来深入分析一下该规定背后的思考. 1 foreach循环 foreach循环(Foreach loop)是计算机编程 ...

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

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

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

    在阅读<阿里巴巴 Java 开发手册>时,发现有一条关于在 foreach 循环里进行元素的 remove/add 操作的规约,具体内容如下:"不要在foreach循环里进行 r ...

  7. kafka java api 删除_使用Java API创建(create),查看(describe),列举(list),删除(delete)Kafka主题(Topic)...

    使用Kafka的同学都知道,我们每次创建Kafka主题(Topic)的时候可以指定分区数和副本数等信息,如果将这些属性配置到server.properties文件中,以后调用Java API生成的主题 ...

  8. java机考_【Java】(机考常用)类集

    类集框架(集合框架)是一个用来代表和操纵集合的统一架构.所有的类集框架都包含如下内容: 接口:是代表类集的抽象数据类型.之所以定义多个接口,是为了以不同的方式操作集合对象. 例如:Collection ...

  9. java skip函数_【Java必修课】图说Stream中的skip()和limit()方法及组合使用

    1 简介 本文将讲解Java 8 Stream中的两个方法:skip()和limit().这两个方法是Stream很常用的,不仅各自会被高频使用,还可以组合出现,并能实现一些小功能,如subList和 ...

最新文章

  1. 哈佛管理论丛:谁背上了令人讨厌的猴子
  2. 准备写java学习笔记
  3. css样式图片、渐变、相关小知识
  4. jxls使用excel公司_使用jXLS将Excel文件解析为JavaBeans
  5. layui内置loading等待加载
  6. [SQL SERVER 2005]数据库差异备份及还原
  7. mysql数据库配置优化(占cpu过高问题)
  8. flume介绍及应用
  9. n 维欧式空间中正交向量组的扩充
  10. 认知盈余时代-知乎如何运营
  11. 代码整洁之道Clean Code笔记
  12. ps动感映像插件ImageMotion 1.3全新功能介绍
  13. 微信、微博、贴吧平台涉嫌违反《网络安全法》被立案调查 审查
  14. python 命令行解析模块_Python命令行解析模块详解
  15. 【Codeforces 1392F】Omkar and Landslide | 思维、结论
  16. 使用php-excel-reader读取excel文件
  17. JAVA游戏土行孙_挖掘机的三种形态《非人学园》土行孙快速上手指南
  18. 独立同分布的中心极限定理
  19. 特征值的几何重复度不大于代数重复度
  20. 神奇的 Python

热门文章

  1. Nature子刊:宏基因组中挖掘原核基因组的分析流程
  2. QIIME 2教程. 15样品分类和回归q2-sample-classifier(2021.2)
  3. EID:宏基因组测序在新发腹泻病毒鉴定中的应用
  4. Microbiome:芝麻菜中肠杆菌科主导核心微生物组并贡献抗生素抗性组
  5. 成年人过敏的N种变态表现
  6. RandomForest:随机森林预测生物标记biomarker——分类
  7. python描述器 触发事件_Python面向对象 - 描述器
  8. R语言构建logistic回归模型并评估模型:计算混淆矩阵、并基于混淆矩阵计算Accuray、Precision、Recall(sensitivity)、F1、Specificity指标
  9. R语言可视化绘图基础知识详解
  10. 梯度消失、梯度爆炸、过拟合问题之神经网络应对方案:数据预处理、批量归一化、非饱和激活函数、梯度缩放和梯度裁剪、权重初始化、提前终止、集成学习、l1l2、Dropout