问题:
我有一个集合,如下,请问,我想判断里面有没有”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的更多相关文章

  1. 理解和解决Java并发修改异常ConcurrentModificationException(转载)

    原文地址:https://www.jianshu.com/p/f3f6b12330c1 理解和解决Java并发修改异常ConcurrentModificationException 不知读者在Java ...

  2. 大杂烩 -- Iterator 并发修改异常ConcurrentModificationException

    基础大杂烩 -- 目录 大杂烩 -- Java中Iterator的fast-fail分析 大杂烩 -- Iterator 和 Iterable 区别和联系 问题: 在集合中,判断里面有没有" ...

  3. 理解和解决Java并发修改异常:ConcurrentModificationException

    參考文獻:https://www.jianshu.com/p/f3f6b12330c1 文獻来源:简书 关键字: Java Exception遇到异常信息Exception in thread &qu ...

  4. 并发修改异常ConcurrentModificationException

    1.简述:在使用 迭代器对象遍历集合时,使用集合对象修改集合中的元素导致出现异常 public static void main(String[] args) { List<Integer> ...

  5. Java基础知识强化之集合框架笔记19:List集合迭代器使用之 并发修改异常的产生原因 以及 解决方案

    1. 我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现. ConcurrentModi ...

  6. java 15 - 8 集合框架(并发修改异常的产生原因以及解决方案)

    问题?   我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现.  面试题: Concu ...

  7. ConcurrentModificationException 集合并发修改异常 解决

    import java.util.ArrayList; import java.util.List; import java.util.ListIterator; /** * 问题? * 有一个集合, ...

  8. ConcurrentModificationException(并发修改异常)的解决

    [异常解释] ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常.[产生的原因] 迭代器是依赖于集合而存在的,在判断成功后,集合 ...

  9. 并发修改异常(ConcurrentModificationException)

    并发修改异常(ConcurrentModificationException) 这个异常,使用集合的时候应该很常见,这个异常产生的原因是因为java中不允许直接修改集合的结构. 先贴上个有趣的例子,给 ...

随机推荐

  1. 【转载】变更MySql数据存储路径的方法

    1.在mysql安装目录下找到my.ini文件,更改#Path to the database root datadir="希望存放数据的地址" 2.将默认存放路径(一般为&quo ...

  2. python Django教程 之模板渲染、循环、条件判断、常用的标签、过滤器

    python3.5 manage.py runserver python Django教程 之模板渲染.循环.条件判断.常用的标签.过滤器 一.Django模板渲染模板 1. 创建一个 zqxt_tm ...

  3. C#如何分割多个空格分隔的字符串?

    using System; using System.Text; using System.Text.RegularExpressions; namespace test { class Progra ...

  4. 表中排序ID断开重排

    客户需要排序ID和页面的问题序号一致,以前删除过一些问题导致order_id 中间有些断开的. 业务表 T_QUESTION order_id question_id  custom_id --1.创 ...

  5. 答:SQLServer DBA 三十问之二:系统DB有哪些,都有什么作用,需不需要做备份,为什么;损坏了如何做还原(主要是master库)

    2. 系统DB有哪些,都有什么作用,需不需要做备份,为什么:损坏了如何做还原(主要是master库): master:它包含一个系统表集合,是整个实例的中央存储库,维护登录账户,其他数据库,文件分布, ...

  6. Oracle 中新增字段后patch

    begin  ad_zd_table.patch('APPLSYS', 'CUX_3_GL_FARMER_BALANCE'); end ;

  7. Application、 session、iewstate,以及repeater 的commang用法

      Session:在不同的浏览器之间传值,像银行之类的网站为了安全把用户名密码保存在session里面.每一台电脑访问服务器,都会是独立的一套session,key值都一样,但是内容都是不一样的 以 ...

  8. Tengine

    Tengine是由淘宝网发起的Web服务器项目.它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性. 外文名 Tengine 发起单位 淘宝网 基    础 Nginx 目    ...

  9. eclipse中jsp文档无语法着色,安装Eclipse Java Web Developer Tools插件

    一.安装Eclipse Java Web Developer Tools插件 1.eclipse菜单:help/install New Software,打开Available Software窗体: ...

  10. Web API的Log问题

    建立了一个Web API项目,在WebApiConfig.cs中已经启用了Tracing. config.EnableSystemDiagnosticsTracing(); 同时web.config中 ...