博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java修改集合抛出ConcurrentModificationException异常
阅读量:6406 次
发布时间:2019-06-23

本文共 1517 字,大约阅读时间需要 5 分钟。

hot3.png

测试代码为:

public static void main(String[] args) {		List
 strList = new ArrayList
(); strList.add("1"); strList.add("2"); strList.add("3"); strList.add("4"); for(String str:strList){ if(str.equals("4")){ strList.remove(str); } } }

运行后结果如下:

155222_FSV6_1375259.png

跟踪代码,抛出异常的地方具体在:

public E next() {            checkForComodification();	    try {		E next = get(cursor);		lastRet = cursor++;		return next;	    } catch (IndexOutOfBoundsException e) {		checkForComodification();		throw new NoSuchElementException();	    }	}

遍历时返回一个元素之前,会调用checkForComodification()函数进行检查,该函数实现为:

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

    modCount 为ArrayList修改的次数,expectedModCount 为期望修改的次数,在删除第四个元素之前,modCount 和expectedModCount 均为4(4次add),而调用ArrayList的remove()方法后,modCount 变为5,但该方法未修改expectedModCount ,其值仍为4,因此出现上述异常。

    解决方法为:单线程环境中,使用 Iterator的remove()方法取代ArrayList的remove()方法,可以避免ConcurrentModificationException异常。

    巧合的是,如果要删除的元素正好是集合中倒数第二个元素,则不会抛出此异常。Iterator遍历获取一个元素之前会先调用hasNext()方法来判断是否还有元素,该方法实现为:

public boolean hasNext() {            return cursor != size();	}

其中cursor为遍历的位置,从0开始,在上面的next()方法中被更新。

    删除倒数第二个元素"3"后,已经访问了3个元素,cursor指向下一个应该访问的元素位置,即3,而size()也返回3,hasNext()返回false,就不会调用next()方法,因此也不存在ConcurrentModificationException异常

    删除元素"4"后,cursor的值变为4,而size()返回3,hasNext()返回true,因此调用next()方法时就会抛出ConcurrentModificationException异常

附上一篇资料:

Java ConcurrentModificationException异常原因和解决方法:

转载于:https://my.oschina.net/HyacinthYuan/blog/494668

你可能感兴趣的文章
go语言与java nio通信,解析命令调用上下文拉起ffmpeg,并引入livego做的简单流媒体服务器...
查看>>
JavaScript面向对象轻松入门之多态(demo by ES5、ES6、TypeScript)
查看>>
【数据结构】线性表(一):顺序列表
查看>>
利用Mallet工具自动挖掘文本Topic
查看>>
Windows下oracle打补丁步骤
查看>>
Python教程(一)Python简介
查看>>
asp.net forms认证
查看>>
Hadoop 公平调度器算法调度解析
查看>>
Linux Foundation(笔记)
查看>>
Java学习第二十五天
查看>>
vim配置
查看>>
ubuntu 把软件源修改为国内源和更新
查看>>
随机产生四则运算,导入导出文件
查看>>
位运算符
查看>>
winform自定义控件
查看>>
C#编码好习惯
查看>>
避其锋芒,侧翼出击。——司马亮创业回忆录(一)
查看>>
scope
查看>>
一起谈.NET技术,晚绑定场景下对象属性赋值和取值可以不需要PropertyInfo
查看>>
一起谈.NET技术,.Net Framework源代码中的模式之Prototype(原型模式)
查看>>