在做项目中用到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. SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  2. 1.spring boot起步之Hello World【从零开始学Spring Boot】

    [视频&交流平台] àSpringBoot视频 http://study.163.com/course/introduction.htm?courseId=1004329008&utm ...

  3. 【转】Exchange Server 的防火墙开放端口

    关于exchange所用到的端口参阅下面的文档, 适用于exchange2010sp2. http://technet.microsoft.com/en-us/library/bb331973.asp ...

  4. 【Social listening实操】如何运用免费的大数据工具获得行业洞察?

    本文转自知乎 作者:苏格兰折耳喵 ----------------------------------------------------- 当我们想要创业却对市场行情不甚了解,该如何迅速了解市场行情 ...

  5. 坑爹的myeclipse 的tomcat 重部署 redeploy !

    启动 tomcat 出现: Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bea ...

  6. PHP微信公共号发送模板消息。

    1.首先从微信公共平台(https://mp.weixin.qq.com/)添加模板. 2. /** * 经纪人生成电子合同通知租客.业主 * @param string $openid openid ...

  7. Flex学习笔记-时间触发器

    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...

  8. Flex学习笔记PopUpMenuButton

    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...

  9. oracle PL/SQL的介绍

    转自:http://blog.sina.com.cn/s/blog_4c302f060101i4o1.html 一 PL/SQL的介绍 1 PL/SQL是什么? PL/SQL(procedural l ...

  10. day03-数据类型

    数据类型 一.介绍 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选的 mysql常用数据类型概括:#1. 数字: 整型:tinyint.int.bi ...