出现的场景:在迭代器对集合进行遍历的同时,集合本身进行变更操作(add(), remove(), set())。

当正常调用时:

import java.util.ArrayList;
import java.util.Iterator; public class TestDemo {
public static void main(String[] args) {
ArrayList<Integer> a = new ArrayList<>();
a.add(1);
a.add(3);
a.add(5);
a.add(6);
Iterator<Integer> iterator = a.iterator();
while (iterator.hasNext()){
System.out.print(iterator.next()+" ");
}
}
}

结果:

当调用interator()接口里面的remove()操作时:

结果:

当调用ArrayList的对象下的remove()或者add();

或者

便会报错:

那么为何会出现这种情况呢?

首先我们应该知道,ArrayList底层的modCount这个属性,这也是个版本记录号每对ArrayList进行一次增删改操作,都会进行modCount++操作。并且在迭代器的使用中,会将当前的modCount的值赋给expectedModCount迭代器的这个属性。

我们先来看看得ArrayList内地迭代器的部分源码:

可以看到每次Iterator的对象调用next()操作时,都会调用checkForComodification()的方法,具体我们来看看这个方法。

再来看看迭代器中的remove()方法:

可以看到迭代器中的remove()方法虽然也是用的ArrayList的remove()方法,正如前面所说,那也会对modCount的值进行改变,但是关键就在于expectedModCount = modCount,它会将改变的值重新赋给expectedModCount。然后每次用完迭代器中的remove()方法后,就算再次用nex()的方法,调用checkForComodification()方法,就不会抛出异常。但是如果直接用ArrayList的对象调用增删改的方法,modCount值得改变,不会引起expectedModCount值的变化,再次调用迭代器,调用到checkForComodification()方法时,便会抛出ConcurrentModificationException的错误。

总的来说,在调用迭代器的时候,就用迭代器的remove()方法,否则就会出现错误,还有迭代器的一个对象只能进行一次迭代,要多次迭代,,便要创建多个对象。

迭代器使用过程中为什么抛出ConcurrentModificationException的更多相关文章

  1. lambda表达式中无法抛出受检异常!

    抛出受检异常的时候,我们的接口应该带上throw关键字,但通过lambda表达式实现的Consumer的accept方法并不带有关键字,因此在lambda表达式中不能抛出受检异常必须把它吃掉

  2. 0xe7f001f0!?NDK调试过程,无故抛出SIGSEGV。

    arm调试过程,如果抛一个SIGSEGV,地址在 0xe7f001f0 附近,原因居然是因为我在调试.当我使用n指令跳到下一行代码时,往往变成了continue指令一样地执行.还不确定地抛出SIGSE ...

  3. JAVA 语言如何进行异常处理,关键字: throws,throw,try,catch,finally分别代表什么意义? 在try块中可以抛 出异常吗?

    Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类, 并提供了良好的接口.        在 Java中,每个异常都是一个对象,它是 Throwable 类或其它子类的实例.当一个方法出 ...

  4. Swift 中异常抛出和四种异常处理

    在Swift中你可以像其他语言一样抛出异常处理异常,今天我们就详细地说说Swift中的异常抛出和处理. 在一开始我们要定义错误或者说是异常,Swift中的一些简单异常可以使用枚举定义,注意这个枚举要继 ...

  5. C# 中异常抛出捕获机制--throw / try,catch,finally

    try { messagebox.show("true"); } catch { messagebox.show("false"); } finally { m ...

  6. java异常处理 throw RuntimeException时不需要同时方法中声明抛出throws 异常等待调用者catch进行捕获 子父类异常问题

    package com.swift.exception1; public class Demo_Exception { public static void main(String[] args) { ...

  7. ArrayList迭代修改抛出ConcurrentModificationException

    extends:http://www.cnblogs.com/dolphin0520/p/3933551.html Iterator<Integer> iterator = list.it ...

  8. ArrayList中的modCount与ConcurrentModificationException

    在看ArrayList源码时,看到了一个字段modCount.在add.remove.clear等方法中都有modCount++的操作.不明白什么意思.点进去看了看该字段的解释,总算明白了.modCo ...

  9. SilverLight抛出 System.InvalidOperationException: 超出了2083 的最大URI

    在SilverLight中对于抛出 System.InvalidOperationException: 超出了 2083 的最大 URI 长度 的异常 处理 其实很简单 在 EntityFramewo ...

随机推荐

  1. git 删除时报 the branch is not fully merged 这是什么意思

    今天删除本地分支 git branch -d XX 提示: the branch XXX is not fully merged原因:XXX分支有没有合并到当前分支的内容 解决方法:使用大写的D 强制 ...

  2. Python--day66--模板语言之fitler回顾

  3. SpringData Jpa、Hibernate、Jpa 三者之间的关系

    JPA规范与ORM框架之间的关系是怎样的呢? JPA规范本质上就是一种ORM规范,注意不是ORM框架--因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服 ...

  4. win10 uwp 手把手教你使用 asp dotnet core 做 cs 程序

    本文是一个非常简单的博客,让大家知道如何使用 asp dot net core 做后台,使用 UWP 或 WPF 等做前台. 本文因为没有什么业务,也不想做管理系统,所以看到起来是很简单. Visua ...

  5. chrome浏览器频繁卡死

    输入chrome:flag 把对应的GPU选项关掉 或者重装 ,从360软件管理器上装

  6. 2019-6-5-WPF-使用封装的-SharpDx-控件

    title author date CreateTime categories WPF 使用封装的 SharpDx 控件 lindexi 2019-6-5 9:4:36 +0800 2018-4-24 ...

  7. H3C RIPv2的改进

  8. P1082 数列分段

    题目描述 对于给定的一个长度为 \(N\) 的正整数数列 \(A_i\) ,现要将其分成连续的若干段,并且每段和不超过 \(M\) (可以等于 \(M\) ),问最少能将其分成多少段使得满足要求. 输 ...

  9. Character.digit()的意义

    最近在阅读Integet.parseInt()源码时,遇到了Character.digit()这个方法,以前没有遇到过,更没使用过,这里查了资料就记录一下. 官方说法是: java.lang.Char ...

  10. thinkjs解决跨域

    this.header("Access-Control-Allow-Origin", "*"); 将上面的代码在请求发送之前执行即可 如果不知道放在哪里 可以参 ...