Iterator中的Itr类(ArrayList)
填坑了,填坑了。
上一篇留的问题,大家都有看吗,哪怕没看,那有放在IDEA中执行吗?
好,我就认为大家都有思考,下面就是到了激动人心,公布答案的时间啦。
按照日常的套路来,答案当然是错误的,恭喜你,都知道答案啦。
好,我们言归正传,来看看他为什么错,错在哪里?
先看代码:
很明显,他是在第36行报错的,也就是在遍历完数值为3的数据报错的。让我们往前顺顺,为什么遍历完第二个元素就报错了,因为他遍历完数值为3的数据后,往list里面增加了一个数值为12的数据。
那我们把遍历里面的if判断去掉试试,答案是肯定正确的。那我们找到了原因,也就是在遍历的时候添加了一个元素,所以导致了他错误。
我们看一下ArrayList中的源码,他在add方法里面做了什么,导致了他在遍历的时候报错。
图一:
图二:
图三:
图四:
上面的四幅图都是层级调用的关系, 也就是在执行确定按钮的时候,先确定list数组的大小,ensureCapacityInternal方法,如果为空数组,就取ArrayList中的常量DEFAULT_CAPACITY作为容器大小,然后增加修改次数modCount,最后比较最小容量和数组长度的大小,考虑扩容的情况。从刚才的叙述来看,他只是增加修改次数modCount,并考虑是否扩容。
那我们来看一下modCount是什么,以及在哪里使用了,让我们回到这个题目。
在第33行,在list数组上定义了一个iterator,我们跟到源码看一下
也就是他创建了一个Itr类,而这个类包括cursor,lastRet,expectedModCount三个变量,hasNext,next,remove三个方法。
那么我们来科普一下这三个变量分别代表什么意思,cursor表示下一个要访问元素的下标,lastRet表示上一个访问元素的下标,expectedModCount表示期望修改次数。
next方法和remove方法在开始的地方都调用了checkForComodification方法,那该方法里面就是判断modCount和expectedModCount次数是否一样,如果不一样,就抛出异常,很明显,我们开始运行代码时的报错信息与该异常相吻合,那其实我们就知道了他其实是在该处抛出的异常信息导致程序报错,那也就是modCount和expectedModCount是不一样的。
下面我们从头开始整理一下整个流程,断点调试一下整个代码。
首先他先构造一个数组,并往里面增加了1,3,2数据,在上面已经看过add方法里面有什么,在add方法里面有增加modCount的值,所以在这里modCount已经为3啦。接着定义了一个iterator,刚才我们知道啦其实也就是新建了一个Itr类,那我们看下在33行结束后,iterator的值是什么
下一个要访问的下标cursor为0,上一个要访问的下标lastRet为-1,预计期望修改次数expectedModCount为3,其实也就是等于他的数组大小size,也就是3。
接着进入35行开始迭代数组,执行hasNext方法,cursor为0,不等于size,为true,继续执行next方法,先判断modCount(也就是3)是否与expectedModCount(也就是3)相等,答案是相等的,再输出该数值1。
接着再进入35行开始迭代数组,执行hasNext方法,cursor为1,不等于size,为true,继续执行next方法,先判断modCount(也就是3)是否与expectedModCount(也就是3)相等,答案是相等的,再输出该数值3。此处注意有if判断。里面有add方法,modCount是要加1的,现在modCount已经变成了4。
接着再进入35行开始迭代数组,执行hasNext方法,cursor为2,不等于size,为true,继续执行next方法,先判断modCount(也就是4)是否与expectedModCount(也就是3)相等,答案是不相等的,抛出异常。
整个流程结束。
归纳:
ArrayList是不能在遍历的时候,在对其进行修改操作的,包括增加和删除。也就是线程不安全的。如果在遍历的过程中有其他线程修改了lsit,则会抛出异常,这就是fast-fail(快速失败策略),这一策略在源码中的体现就是在next方法的时候,会调用checkForComodification方法,通过比较modCount和expectedModCount两者的是否相等,判断是否在遍历的时候,有进行修改操作,从而确定是否要抛出异常。那么在需要保证数组在遍历的时候不进行修改操作的时候,可以优先使用iterator来遍历。
Iterator中的Itr类(ArrayList)相关推荐
- java list 分组_Java 将List中的实体类按照某个字段进行分组并存
1.JDK1.8之前: 假设有实体类User,里面有字段id,我们将相同id的User进行分组,并存放在Map中.(例子不是很恰当,但很能说明问题) public static void main(S ...
- JAVA语言中 文本框类的类名是_这是什么?
[简答题]设计一个Printer类继承Output和Product接口,实现数据的获取和输出 (25.0分) [多选题]一般Java程序的类主体由哪两部分组成( ). [多选题]如果子类中的( )与父 ...
- 集合专辑(二):List实现类ArrayList解读
ArrayList解读 简介 ArrayList是Java集合中出场率最多的一个类. 结构图 如果实现AbstractList 源码分析 javaDoc分析 静态变量 成员变量 构造方法 重要方法解读 ...
- Java知识点04——集合(Set、List、Queue、Map、Collection和Iterator、Collections工具类)
Java知识点04--集合(Set.List.Queue.Map.Collection.Iterator.Collections工具类) 一.集合 1.1 集合概述 二.Collection 2.1 ...
- HDFS中的Diff类——用来描述两个集合的不同
HDFS中的Diff类--用来描述两个集合的不同 概述 Diff类,用来描述集合状态的变化,e.g. 集合中存在元素{e1, e2, e3},假设集合状态为previous 向集合中添加元素e4,此时 ...
- python中的新式类与旧式类的一些基于descriptor的概念(下)
3. Descriptor介绍 3.1 Descriptor代码示例 3.2 定义 3.3 Descriptor Protocol(协议) 3.4 Descriptor调用方法 4. 基于Descri ...
- 标准C++中的string类的用法总结
相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有没有这样使用起来非常方便的类呢?答案是肯 ...
- 《JAVA练习题目10》请对图书馆系统中的CatalogItem类、Book类和Recording类进行改造,实现其code属性的自动编码。
请对图书馆系统中的CatalogItem类.Book类和Recording类进行改造,实现其code属性的自动编码.具体要求如下: Book实例的编号从B001开始,每次新增一个实例,编号自动加一,即 ...
- WebService中使用自定义类的解决方法(5种)
转自:http://www.cnblogs.com/lxinxuan/archive/2007/05/24/758317.html Demo下载:http://files.cnblogs.com/lx ...
最新文章
- hust1347(归并排序求逆序对)
- select2 change之前的改变
- 微信公众号sae服务器搭建,SAE 搭建微信公众平台
- Java实现通过ssh远程连接主机并执行命令
- UNIX环境高级编程之第7章:进程环境
- Altium Designer 20查找指定元器件
- linux设备/dev/dsp,/dev/mixer
- NAS媒体库资源归集整理工具nas-tools
- Java学习笔记-不定时更新
- Windows 11 (updated Dec 2021) 简体中文版、英文版(64-bit、ARM64)下载(2022 年 1 月发布)
- php访问80端口强制跳转443,nginx 80端口重定向到443端口
- webservice 缺少根元素_知识点:高中化学氮元素及其化合物知识总结
- PointConv:基于3D点云的深度卷积网络
- Word2010下划线不显示
- 2019年的第一场雪来的既猛又烈,突然想分享点东西
- mos中Port-Specific的意思
- 用u盘重装微软官方win10专业版--详细操作文档
- 【干货篇】调用其他系统http接口超时了,如何处理,方案汇总
- 超市自动收款机php,自助收银机,超市无人自动收银系统,海信自助POS,自助收款机...
- 计算机博后 国外招聘,全额奖学金机会,香港理工计算机系博后/博士/研究助理招收中...
热门文章
- 西海情歌用计算机怎么弹,西海情歌-降央卓玛-和弦谱-《弹吧》官网tan8.com-和弦谱大全,学吉他,秀吉他...
- 【学术渣杂谈】CCF-A类会议汇总(人工智能方向)
- java网上书店管理系统(1.登录界面)
- Android不同手机屏幕分辨率自适应【转】
- 网络通信误码率测试软件,DMR终端直通模式误码率测试软件的设计与实现
- 易买网更多新闻代码_新闻 | 1018MAMAMOO公布了颂乐与华莎主题海报等更多资讯
- Arduino安装全流程(包括ESP32离线包安装)-支持到2.0.9
- k8s hostPath
- C语言实现直角坐标转换为极坐标
- 如何测试你的即时通讯实时音视频开发方案