集合框架之——迭代器并发修改异常ConcurrentModificationException
问题:
我有一个集合,如下,请问,我想判断里面有没有”world”这个元素,如果有,我就添加一个”javaee”元素,请写代码实现。
使用普通迭代器出现的异常:
ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
产生的原因:
迭代器是依赖于集合而存在的,在判断成功后,集合的中新添加了元素,而迭代器却不知道,所以就报错了,这个错叫并发修改异常。
其实这个问题描述的是:普通迭代器遍历元素的时候,通过集合是不能修改元素的。
解决:
A:迭代器迭代元素,迭代器修改元素
元素是跟在刚才迭代的元素后面的。
B:集合遍历元素,集合修改元素(普通for循环进行遍历)
元素是在最后添加的。
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator; public class ListIteratorDemo2 {
public static void main(String[] args) {
// 创建List集合对象
List list = new ArrayList();
// 添加元素
list.add("hello");
list.add("world");
list.add("java"); // 普通迭代器遍历
// Iterator it = list.iterator();
// while (it.hasNext()) {
// String s = (String) it.next();
// if ("world".equals(s)) {
// list.add("javaee"); //这里报错!!!!
// }
// } 方式1:迭代器迭代元素,迭代器修改元素
而Iterator迭代器却没有添加功能,所以我们使用其子接口ListIterator
ListIterator lit = list.listIterator();
while (lit.hasNext()) {
String s = (String) lit.next();
if ("world".equals(s)) {
lit.add("javaee");
}
} 方式2:集合遍历元素,集合修改元素(普通for)
for (int x = 0; x < list.size(); x++) {
String s = (String) list.get(x);
if ("world".equals(s)) {
list.add("javaee");
}
} System.out.println("list:" + list);
}
}
另外,尤其值得注意的是此迭代器remove()方法的使用:从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。每次调用 next 只能调用一次此方法。如果进行迭代时用调用此方法(remove方法)之外的其他方式修改了该迭代器所指向的 collection,则迭代器的行为是不确定的。 接口设计人员在设计Iterator<T>接口的时候已经指出,在进行迭代时如果调用了除了迭代器的remove()方法修改了该迭代器所指向的collection,则会造成不确定的后果。具体出现什么后果依迭代器的具体实现而定。针对这种不确定的后果可能出现的情况,在学习ArrayList时遇到了其中一种:迭代器抛出 ConcurrentModificationException异常。具体异常情况如下代码所示:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator; public class ItaratorTest { public static void main(String[] args) {
Collection<String> list = new ArrayList<String>();
list.add("Android");
list.add("IOS");
list.add("Windows Mobile"); Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String lang = iterator.next();
list.remove(lang);//will throw ConcurrentModificationException
}
} }
此段代码在运行时会抛出ConcurrentModificationException异常,因为我们在迭代器运行期间没有用iterator的remove()方法来删除元素,而是使用ArrayList的 remove()方法改变了迭代器所指向的collection。这就违反了迭代器的设计原则,所以发生了异常。
总结:
- 在用迭代器Iterator遍历collection时,如果要在遍历期间修改collection,则必须通过Iterator/listIterator来实现,否则可能会发生“不确定的后果”。
集合框架之——迭代器并发修改异常ConcurrentModificationException的更多相关文章
- 理解和解决Java并发修改异常ConcurrentModificationException(转载)
原文地址:https://www.jianshu.com/p/f3f6b12330c1 理解和解决Java并发修改异常ConcurrentModificationException 不知读者在Java ...
- 大杂烩 -- Iterator 并发修改异常ConcurrentModificationException
基础大杂烩 -- 目录 大杂烩 -- Java中Iterator的fast-fail分析 大杂烩 -- Iterator 和 Iterable 区别和联系 问题: 在集合中,判断里面有没有" ...
- 理解和解决Java并发修改异常:ConcurrentModificationException
參考文獻:https://www.jianshu.com/p/f3f6b12330c1 文獻来源:简书 关键字: Java Exception遇到异常信息Exception in thread &qu ...
- 并发修改异常ConcurrentModificationException
1.简述:在使用 迭代器对象遍历集合时,使用集合对象修改集合中的元素导致出现异常 public static void main(String[] args) { List<Integer> ...
- Java基础知识强化之集合框架笔记19:List集合迭代器使用之 并发修改异常的产生原因 以及 解决方案
1. 我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现. ConcurrentModi ...
- java 15 - 8 集合框架(并发修改异常的产生原因以及解决方案)
问题? 我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现. 面试题: Concu ...
- ConcurrentModificationException 集合并发修改异常 解决
import java.util.ArrayList; import java.util.List; import java.util.ListIterator; /** * 问题? * 有一个集合, ...
- ConcurrentModificationException(并发修改异常)的解决
[异常解释] ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常.[产生的原因] 迭代器是依赖于集合而存在的,在判断成功后,集合 ...
- 并发修改异常(ConcurrentModificationException)
并发修改异常(ConcurrentModificationException) 这个异常,使用集合的时候应该很常见,这个异常产生的原因是因为java中不允许直接修改集合的结构. 先贴上个有趣的例子,给 ...
随机推荐
- eclipse下的webservice开发
关于eclipse下的webservice开发,有非常多的教程,这里只记下学习过程中的弯路: 1.无论是CXF模式还是AXIS模式,在出现start server之后,点击next报错:"s ...
- 预装WIN8系统的电脑安装WIN7的方法
前些天,给一位客户的本本安装WIN7,因为原来预装了WIN8,结果按常规方法安装一直没有成功,不管是光盘还U盘.所以心里一直有个疑问,所以留意查阅了有关资料和相关的文章,终于明白了问题所在,现在在这里 ...
- 九、数据库——sql server 2008导入excel
昨天分配给我一个活,让我手动录入新闻网页的数据,包括每条新闻的标题.时间和链接. 一开始,就是按照最原始的手动录入的方法,一条条的录入.发现这简直就是在浪费时间,于是就想了一种新方法. 1.将网页中的 ...
- 3.1 ARM汇编编程概述
1. 汇编编程 为什么要学习汇编 1). Bootloader初始化 2). Linux kernel 3). 高效 2. ARM汇编分类 1. ARM标准汇编:ARM公司得汇编器适合在Windows ...
- openwrt编译环境搭建
1,首先安装ubuntu系统,这里安装的是虚拟机 2,安装openwrt编译所需环境 apt-get install build-essential libncures5-dev gawk libs ...
- Linux cache释放
cache释放: To free pagecache: > /proc/sys/vm/drop_caches To free dentries and inodes: > /proc/sy ...
- Android中editText使用报错
在activity_main.xml文件中添加了editText控件 <EditText android:id="@+id/edit_text" ...
- Android IOS WebRTC 音视频开发总结(二五)-- webrtc优秀资源汇总
本文主要整理一些webrtc相关资料供学习(会持续更新),转载请说明出处,文章来自博客园RTC.Blacker,欢迎关注微信公众号:blackerteam ---------------------- ...
- java8中map的meger方法的使用
java8中map有一个merge方法使用示例: /** * 打印出包含号码集的label的集合 * * @param args */ public static void main(String[] ...
- 阿里中间件——diamond
一.前言 最近工作不忙闲来无事,仔细分析了公司整个项目架构,发现用到了很多阿里巴巴集团开源的框架,今天要介绍的是中间件diamond. 二.diamond学习笔记 1.diamond简介 diamon ...