在做项目中用到List存储数据,在里面做数据操作时候用到了删除。结果抛出ConcurrentModificationException异常。在这里把问题总结一下。

原因:

ArrayList进行foreach时所调用的迭代器(内部迭代器Itr)
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
// expectedModCount是Itr特有的,modCount是公共的
// expectedModCount和modCount默认是两者相等的;ArrayList进行删除修改都会更新modCount的值
// 当ArrayList通过foreach进入它的内部迭代器Itr时,expectedModCount就被赋值为modCount的值,后续ArrayList进行增加或删除,只会更新modCount,而不会同步更新expectedModCount
// 所以迭代器根据这两个值进行判断是否有并发性修改
int expectedModCount = modCount;
 
public boolean hasNext() {
return cursor != size;
}
// ArrayList通过foreach(即增强for循环)来循环是调用的是ArrayList中内部类Itr的next()
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
// ArrayList中迭代器删除方法
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
 
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
// 通过ArrayList中foreach(即通过ArrayList内部Itr的迭代器)进行删除元素
// 此时会进行赋值 expectedModCount = modCount;而不会抛出异常
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
ArrayList通过foreach迭代是调用的其内部类Itr的next方法。如果通过foreach循环,要去除某些元素,只能通过迭代器删除。因为迭代器删除后会对expectedModCount = modCount设置,不会再循环过程因为expectedModCount 和 modCount值不相等而抛出异常了。如果是通过ArrayList的删除则只会对modCount进行更新,但是ArrayList内部迭代器Itr的属性expectedModCount却没有得到更新,所以抛异常。
 
解决: List.iterator() 直接用迭代器去迭代,然后去删除元素。
 

ArrayList删除--------ConcurrentModificationException问题的更多相关文章

  1. ArrayList的ConcurrentModificationException异常和多线程下的异常

    一.ConcurrentModificationException ArrayList源码看为什么出现异常: public class ArrayList<e> extends Abstr ...

  2. ArrayList中ConcurrentModificationException

    java中两种基本的集合结构ArrayList和LinkedList底层有两种不同的存储方式实现,ArrayList为数组实现,属于顺序存储,LinkedList为链表实现,属于链式存储,在对Arra ...

  3. Android 两个ArrayList找出相同元素及单个ArrayList删除元素

    //从一个ArrayList中删除重复元素 List<String> arrayList1 = new ArrayList<String>(); arrayList1.add( ...

  4. ArrayList删除特定元素的方法

    最朴实的方法,使用下标的方式: ArrayList<String> al = new ArrayList<String>(); al.add("a"); a ...

  5. ArrayList在foreach正常迭代删除不报错的原因

    一.背景 在以前的随笔中说道过ArrayList的foreach迭代删除的问题:ArrayList迭代过程删除问题 按照以前的说法,在ArrayList中通过foreach迭代删除会抛异常:java. ...

  6. ArrayList的删除姿势你都知道了吗

    引言 前几天有个读者由于看了<ArrayList哪种遍历效率最好,你真的弄明白了吗?>问了个问题普通for循环ArrayList为什么不能删除连续重复的两个元素?其实这个描述是不正确的.正 ...

  7. jdk源码分析之ArrayList

    ArrayList关键属性分析 ArrayList采用Object数组来存储数据 /** * The array buffer into which the elements of the Array ...

  8. subList ArrayList LinkedList

    List<E> subList(int fromIndex,int toIndex) 该方法返回原有集合从fromIndex 到 toIndex之间一部分数据,组成一个新的集合,这两个集合 ...

  9. 死磕 java集合之ArrayList源码分析

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. 简介 ArrayList是一种以数组实现的List,与数组相比,它具有动态扩展的能力,因此也可 ...

随机推荐

  1. hive之窗口函数

    窗口函数 1.相关函数说明 COVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化 CURRENT ROW:当前行 n PRECEDING:往前n行数据 n FOLLO ...

  2. lampp中的ftp使用介绍

    搭建完毕lampp 具体要求如下:使用Lampp的proftpd,开通多个FTP用户,并各分配一个目录,而且需要限制用户在自己的目录里面,可以自由读写. 操作步骤:第一步:设置ftp用户组,输入命令: ...

  3. 精通Web Analytics 2.0 (12) 第十章:针对潜在的网站分析陷阱的最佳解决方案

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第十章:针对潜在的网站分析陷阱的最佳解决方案 是时候去处理网站分析中最棘手的一些问题了,然后获得属于你的黑带,这是成为分析忍者的 ...

  4. Python基础2 列表 字典 集合

    本节内容 列表.元组操作 字符串操作 字典操作 集合操作 文件操作 字符编码与转码 1. 列表.元组操作 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 定义列表 ...

  5. electron 项目的打包方式,以及 jquery 插件的修改使用

    < 一 > 应用打包 1,首先确定安装了 node 和 npm 2,全局安装打包依赖  => npm i electron-packager -g 3,打包命令 electron-p ...

  6. centos7.5安装golang

    1.下载 [root@localhost bin]#wget https://dl.google.com/go/go1.10.2.linux-amd64.tar.gz [root@localhost ...

  7. Django之集合函数使用与mysql表的创建特殊字段分析

    1. 集合函数的使用场景: -- 单独使用: 不分组, 只查聚合结果 -- 分组使用: 按字段分组, 可查询分组字段与聚合结果 2. 导入聚合函数 from django.db.models impo ...

  8. Excel和Word 简易工具类,JEasyPoi 2.1.7 版本发布

    JEasyPOI 简介 EasyPOI 功能如同名字easy,追求的就是简易,让一个没接触过poi的人员,可以傻瓜化的快速实现Excel导入导出.Word模板导出,可以仅仅5行代码就可以完成Excel ...

  9. JeeWx捷微3.1小程序版本发布,支持微信公众号,微信企业号,支付窗——JAVA版开源微信管家

    支持小程序,JeeWx捷微3.1小程序版本发布^_^ JeeWx捷微V3.1——多触点小程序版本管理平台(支持微信公众号,微信企业号,支付窗)   JeeWx捷微V3.1.0版本紧跟微信小程序更新,在 ...

  10. Linux下使用命令行配置IPMI

    ipmitool是什么: 百度百科给的解释已经够用了,简单说就是“IPMI(Intelligent Platform Management Interface)即智能平台管理接口是使硬件管理具备“智能 ...