填坑了,填坑了。

上一篇留的问题,大家都有看吗,哪怕没看,那有放在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)相关推荐

  1. java list 分组_Java 将List中的实体类按照某个字段进行分组并存

    1.JDK1.8之前: 假设有实体类User,里面有字段id,我们将相同id的User进行分组,并存放在Map中.(例子不是很恰当,但很能说明问题) public static void main(S ...

  2. JAVA语言中 文本框类的类名是_这是什么?

    [简答题]设计一个Printer类继承Output和Product接口,实现数据的获取和输出 (25.0分) [多选题]一般Java程序的类主体由哪两部分组成( ). [多选题]如果子类中的( )与父 ...

  3. 集合专辑(二):List实现类ArrayList解读

    ArrayList解读 简介 ArrayList是Java集合中出场率最多的一个类. 结构图 如果实现AbstractList 源码分析 javaDoc分析 静态变量 成员变量 构造方法 重要方法解读 ...

  4. Java知识点04——集合(Set、List、Queue、Map、Collection和Iterator、Collections工具类)

    Java知识点04--集合(Set.List.Queue.Map.Collection.Iterator.Collections工具类) 一.集合 1.1 集合概述 二.Collection 2.1 ...

  5. HDFS中的Diff类——用来描述两个集合的不同

    HDFS中的Diff类--用来描述两个集合的不同 概述 Diff类,用来描述集合状态的变化,e.g. 集合中存在元素{e1, e2, e3},假设集合状态为previous 向集合中添加元素e4,此时 ...

  6. python中的新式类与旧式类的一些基于descriptor的概念(下)

    3. Descriptor介绍 3.1 Descriptor代码示例 3.2 定义 3.3 Descriptor Protocol(协议) 3.4 Descriptor调用方法 4. 基于Descri ...

  7. 标准C++中的string类的用法总结

    相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有没有这样使用起来非常方便的类呢?答案是肯 ...

  8. 《JAVA练习题目10》请对图书馆系统中的CatalogItem类、Book类和Recording类进行改造,实现其code属性的自动编码。

    请对图书馆系统中的CatalogItem类.Book类和Recording类进行改造,实现其code属性的自动编码.具体要求如下: Book实例的编号从B001开始,每次新增一个实例,编号自动加一,即 ...

  9. WebService中使用自定义类的解决方法(5种)

    转自:http://www.cnblogs.com/lxinxuan/archive/2007/05/24/758317.html Demo下载:http://files.cnblogs.com/lx ...

最新文章

  1. hust1347(归并排序求逆序对)
  2. select2 change之前的改变
  3. 微信公众号sae服务器搭建,SAE 搭建微信公众平台
  4. Java实现通过ssh远程连接主机并执行命令
  5. UNIX环境高级编程之第7章:进程环境
  6. Altium Designer 20查找指定元器件
  7. linux设备/dev/dsp,/dev/mixer
  8. NAS媒体库资源归集整理工具nas-tools
  9. Java学习笔记-不定时更新
  10. Windows 11 (updated Dec 2021) 简体中文版、英文版(64-bit、ARM64)下载(2022 年 1 月发布)
  11. php访问80端口强制跳转443,nginx 80端口重定向到443端口
  12. webservice 缺少根元素_知识点:高中化学氮元素及其化合物知识总结
  13. PointConv:基于3D点云的深度卷积网络
  14. Word2010下划线不显示
  15. 2019年的第一场雪来的既猛又烈,突然想分享点东西
  16. mos中Port-Specific的意思
  17. 用u盘重装微软官方win10专业版--详细操作文档
  18. 【干货篇】调用其他系统http接口超时了,如何处理,方案汇总
  19. 超市自动收款机php,自助收银机,超市无人自动收银系统,海信自助POS,自助收款机...
  20. 计算机博后 国外招聘,全额奖学金机会,香港理工计算机系博后/博士/研究助理招收中...

热门文章

  1. 西海情歌用计算机怎么弹,西海情歌-降央卓玛-和弦谱-《弹吧》官网tan8.com-和弦谱大全,学吉他,秀吉他...
  2. 【学术渣杂谈】CCF-A类会议汇总(人工智能方向)
  3. java网上书店管理系统(1.登录界面)
  4. Android不同手机屏幕分辨率自适应【转】
  5. 网络通信误码率测试软件,DMR终端直通模式误码率测试软件的设计与实现
  6. 易买网更多新闻代码_新闻 | 1018MAMAMOO公布了颂乐与华莎主题海报等更多资讯
  7. Arduino安装全流程(包括ESP32离线包安装)-支持到2.0.9
  8. k8s hostPath
  9. C语言实现直角坐标转换为极坐标
  10. 如何测试你的即时通讯实时音视频开发方案