每个实现Iterable接口的类必须提供一个iterator方法,返回一个Iterator对象,ArrayList也不例外

public Iterator<E> iterator() {
return new Itr();
}

返回的是一个Itr类的对象,接下来我们来看它的部分源码

protected transient int modCount = 0;

private class Itr implements Iterator<E> {

		// 指向下一个要被迭代的元素
int cursor;
// 指向当前元素
int lastRet = -1;
// 将modCount赋值给expectedModCount
int expectedModCount = modCount;

这里主要先看一下一个重点,modCount

modCount顾名思义就是修改次数,每次对ArrayList内容的修改都将增加这个值

Fail-Fast 机制

modCount主要是为了防止在迭代过程中通过List的方法(非迭代器)改变了原集合,导致出现不可预料的情况,从而提前抛出并发修改异常,注意是“提前“,这可能也是Fail-Fast机制命名的由来。在可能出现错误的情况下提前抛出异常终止操作,如下:

ArrayList<Integer> arrayList = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
arrayList.add(i);
} Iterator iterator = arrayList.iterator(); while (iterator.hasNext()) {
arrayList.remove(1);
iterator.next();
}

这段代码最终会抛出ConcurrentModificationException

原因是因为,在迭代器进行遍历的时候,如果 iterator.next()选择了需要遍历的下一个目标时(假设这个目标为坐标3的数),



我却调用了arrayList.remove(1)将坐标1给删了,那么这时候它就会遍历成原本坐标为4的数字4,却没有遍历数字3了,如果是LinkedList,会直接找不到目标



为了防止这种情况,在迭代器初始化过程中会将modCount赋给迭代器的 expectedModCount。在迭代过程中,判断 modCount 跟 expectedModCount 是否相等,如果不相等就表示通过其他方法修改了 ArrayList的结构

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

为什么说是其他方法呢?因为Iterator的remove方法和ArrayList的不一样

public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification(); try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}

它在每一次删除之后都会将cursor(下一项)的位置设置为当前位置,也就是将cursor往前移动了一位,之后再将modCount赋值给expectedModCount使它们保持相等。





这样就不会产生ConcurrentModificationException异常了

ArrayList中的Iterator详解的更多相关文章

  1. [转载]Java迭代器(iterator详解以及和for循环的区别)

    Java迭代器(iterator详解以及和for循环的区别) 觉得有用的话,欢迎一起讨论相互学习~[Follow] 转载自 https://blog.csdn.net/Jae_Wang/article ...

  2. C++中的STL中map用法详解(转)

    原文地址: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html C++中的STL中map用法详解   Map是STL的一个关联容器,它提供 ...

  3. [转载]java中import作用详解

    [转载]java中import作用详解 来源: https://blog.csdn.net/qq_25665807/article/details/74747868 这篇博客讲的真的很清楚,这个作者很 ...

  4. php中关于引用(&)详解

    php中关于引用(&)详解 php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的变量名访问同一个变量内容. 与C语言中的指针是有差别的.C语言中的 ...

  5. JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解

    二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...

  6. AngularJS select中ngOptions用法详解

    AngularJS select中ngOptions用法详解   一.用法 ngOption针对不同类型的数据源有不同的用法,主要体现在数组和对象上. 数组: label for value in a ...

  7. 【转载】C/C++中extern关键字详解

    1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...

  8. oracle中imp命令详解 .

    转自http://www.cnblogs.com/songdavid/articles/2435439.html oracle中imp命令详解 Oracle的导入实用程序(Import utility ...

  9. Android中Service(服务)详解

    http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...

随机推荐

  1. 7-43 jmu-python-字符串异常处理 (20 分)

    输入一行字符串及下标,能取出相应字符.程序能对不合法数据做相应异常处理. 输入格式: 行1:输入一字符串 行2:输入字符下标 输出格式: 下标非数值异常,输出下标要整数 下标越界,输出下标越界 数据正 ...

  2. [React技术内幕] setState的秘密

    对于大多数的React开发者,setState可能是最常用的API之一.React作为View层,通过改变data从而引发UI的更新.React不像Vue这种MVVM库,直接修改data并不能视图的改 ...

  3. 利用ajax 引入静态页公共的头部与底部

    利用ajax引入公共的头部与底部或者多个页面需要用到的重复的组件,对于新入门的前端来说是很实用的方法,自己也是新手菜鸟一枚,折腾了好久,实现的方法有很多种,这是我个人觉得比较简单方便的 首先得把公用的 ...

  4. 前端每日实战:123# 视频演示如何用纯 CSS 创作一架双冀飞机

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/yxVYRL 可交互视频 此视频是可 ...

  5. CSS3实现一个旋转的花朵

    要效果图如下: 实现原理:其实很简单,就是中间的圆圈定位在中间,其他的6个圆圈,进行不同的绝对定位,然后进行旋转!代码: <!DOCTYPE html> <html lang=&qu ...

  6. .Net Core WebApi在Linux上启动和关闭

    测试机器:阿里云云主机1核2g 安装环境:centos-7 服务器:Nginx 1.17.1 测试默认已启动 已安装配置:.Net Core 3.1 测试默认安装 连接配置:x-ftp,x-shell ...

  7. SpringBoot是如何实现自动配置的?--SpringBoot源码(四)

    注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 前言 本篇接 助力SpringBoot自动配置的条件注解ConditionalOnXXX分析--SpringBoot源码(三 ...

  8. 将root用户权限赋予普通用户

    将root用户权限赋予普通用户 普通用户想要拥有root用户的权限,必须修改/etc/sudoers文件 ,还必须使用visudo命令修改.一是因为这个命令能防止多个用户同时修改这个文件,二是能进行有 ...

  9. juery 弹出框

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. js 实现端口列表话

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...