ArrayList foreach 循环里进行元素的 remove add 操作有什么现象?

先来看看《阿里巴巴Java开发手册》中的一段

【强制】不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator
方式,如果并发操作,需要对 Iterator 对象加锁。
反例:
List<String> a = new ArrayList<String>();
a.add("1");
a.add("2");
for (String temp : a) {
    if("1".equals(temp)){
        a.remove(temp);
    }
}
说明:这个例子的执行结果会出乎大家的意料,那么试一下把“1”换成“2”,会是同样的结
果吗?
正例:
Iterator<String> it = a.iterator();
while(it.hasNext()){
    String temp = it.next();
    if(删除元素的条件){
        it.remove();
    }
} 

当1的时候,能够正确输出remove 以后的ArrayList 当2的时候,抛出了 ConcurrentModificationException

看一段ArrayList 的forEachRemaining 方法的源码

final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}

本质上是隐式的 iterator 由于没有重新设置 expectedModCount ,当你使用 list.remove() 后遍历执行 iterator.next() 时就会报ConcurrentModificationException

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JavaQ

HashMap死循环精简说

在JDK1.8之前的版本中,HashMap的底层实现是数组+链表。当调用HashMap的put方法添加元素时,如果新元素的hash值或key在原Map中不存在,...

12330
来自专栏androidBlog

HashMap及HashTable源码解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/...

9110
来自专栏Java爬坑系列

【Java入门提高篇】Day24 Java容器类详解(七)HashMap源码分析(下)

13830
来自专栏DT乱“码”

正则判断工具类

package com.gulf.utils; import java.text.ParseException; import java.text.Simpl...

290100
来自专栏desperate633

HashSet实现原理分析(Java源码剖析)add(E e)remove(Object o)iterator()小结

本文将深入讨论HashSet实现原理的源码细节。在分析源码之前,首先我们需要对HashSet有一个基本的理解。

31130
来自专栏desperate633

LintCode 子集题目代码

8630
来自专栏老付的网络博客

Java中的容器

在Java中有常用的三种类型的容器,分别是List 、Map、Set,基于这个三个基本的类型,派生出很多其它的类型,具体关系如下:

50020
来自专栏算法channel

二叉树非递归版的中序遍历算法

本公众号主要推送关于对算法的思考以及应用的消息。算法思想说来有,分而治之,搜索,动态规划,回溯,贪心等,结合这些思想再去思考如今很火的大数据,云计算和机器学习,...

36250
来自专栏Java技术栈

Java List面试题汇总

1、你知道的List都有哪些? 2、List和Vector有什么区别? 3、List是有序的吗? 4、ArrayList和LinkedList的区别?分别用在什...

42190
来自专栏WD学习记录

Python数据结构与算法笔记(4)

前序遍历中,我们首先访问根节点,然后递归地做左侧子树的前序遍历,随后是右侧子树的递归前序。

13720

扫码关注云+社区

领取腾讯云代金券