ArrayList的迭代器的使用,在ArrayList中,通过调用iterator()就可以完成迭代器的创建。代码如下:

public Iterator iterator() {        return new Itr(); }

由上面的源码可知,在iterator方法内部创建了创建了一个Itr类型,该类是定义在ArrayList中的一个私有内部类,它实现了Iterator接口。

在jdk1.8中,接口Iterator一共有四个方法:

//是否还有下一个元素boolean hasNext();//下一个元素E next();//删除当前的元素void remove(); //对list中的每个元素进行action操作void forEachRemaining(Consumer super E> action);

内部类Itr它有三个属性,对Iterator接口的方法实现是依赖下面三个属性。

//当前元素的索引位置int cursor;  //上一个元素的索引位置,主要用在Iterator的remove操作中。int lastRet = -1; //记录当前list修改的次数,使用当前list中的modCount来初始化int expectedModCount = modCount;

下面先介绍Iterator的每个方法的实现:

public boolean hasNext() {            return cursor != size;}

hasNext方法比较简单,判断下一个元素的索引是否与list大小相等,如果相等,表示当前元素已经是list中的最后一个元素。下面介绍next方法,该方法是获取当前元素:

public E next() {            checkForComodification();            int i = cursor;            if (i >= size)                throw new NoSuchElementException();            Object[] elementData = ArrayList.this.elementData;            if (i >= elementData.length)                throw new ConcurrentModificationException();            cursor = i + 1;            return (E) elementData[lastRet = i];}

首先通过 checkForComodification()检查在执行Iterator遍历的时候,如果有其他线程对该list进行了修改,那么会抛出异常。在内部使用i变量来代替cursor,接着判断i的值的合法性,然后给cursor完成加一操作,并且把当前i的值赋给lastRet并返回elementData[i]

下面介绍remove方法,

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();            }}

由源码可知,指向删除操作其实是删除lastRet所执行的元素,而lastRet初始值是-1,因此当通过Iterator进行remove操作的时候,必须现在执行next()操作,获取到list中的第一个元素之后,才能执行remove方法。由上面源码可知当执行完成 ArrayList.this.remove(lastRet)操作后,lastRet又重新被赋值为-1,因此不同通过Iterator对list连续做两次remove操作。

下面介绍最后一个方法,也是1.8新增加的一个方法,该方法主要是对通过Iterator遍历后,对list剩余元素进行consumer操作。

public void forEachRemaining(Consumer super E> consumer) {            Objects.requireNonNull(consumer);            final int size = ArrayList.this.size;            int i = cursor;            if (i >= size) {                return;            }            final Object[] elementData = ArrayList.this.elementData;            //这里第二次判断合法性主要是预防其他线程对该list有增删的操作           //当其他线程对list进行了曾删操作,那么该方法会抛出异常,退出当前方法            if (i >= elementData.length) {                throw new ConcurrentModificationException();            }           //每次对List中剩余的元素进行consumer操作时,都需要来判断一下list           //有没有被其他线程进行过增删改的操作            while (i != size && modCount == expectedModCount) {                consumer.accept((E) elementData[i++]);            }            cursor = i;            lastRet = i - 1;            checkForComodification(); }

首先是对cursor值的合法性进行判断,然后是再次获取elementData的大小,再判断一次是否List被其他线程进行过元素的增加和删除操作。校验完成之后,就是开始对List中的每个元素执行consumer操作,每次操作后通过判断modCount == expectedModCount来检查是否有其他线程对该list进行过修改操作。如果有,那么就会退出当前循环,并且把cursor的指向List已经执行consumer操作的最后一个元素的索引,最后通过调用checkForComodification()抛出异常;否则,顺利执行完循环,并且最后还是要执行一次checkForComodification(),检查是否在执行forEachRemaining的时候,有其他线程对list进行增删改操作。checkForComodification方法比较简单,这里不做太多说明,具体见下面:

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

实现文本编辑器的设计与实现_ArrayList实现分析(三)——迭代器的实现相关推荐

  1. java文本编辑器课程设计报告_java课程设计报告 心得体会——计算器、文本编辑器.doc...

    java课程设计报告 心得体会--计算器.文本编辑器.doc 还剩 24页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价低环保! 内 ...

  2. java 课程设计文本编辑器,JAVA课程设计--文本编辑器

    JAVA课程设计--文本编辑器 Java 语言课程期末作业 1 Java 语言课程期末作业 题 目 第 8 题,文本编辑器 学 院 计算机学院 专 业 计算机科学与技术 班 别 学 号 姓 名 201 ...

  3. python多功能文本编辑器_多功能文本编辑器(EditPad Pro)

    EditPad Pro 是一款多功能文本编辑器,设计的目标就是在保持程序小巧简洁的同时,提供所有基础编辑功能.EditPad Pro 可以在 Windows 98.Me.NT4.2000.XP.Vis ...

  4. c#实现类似Sublime Text文本编辑器、电脑屏幕画板

    一.前言 需要源码请留言,环境配置请留言,项目运行时报错请留言 结课设计,使用vs2017开发winForm窗体应用程序,包括简单的sublime text文本编辑器.屏幕画板程序. 文本编辑器:设计 ...

  5. Ubuntu下几种常用的文本编辑器

    常见的基于控制台的文本编辑器有以下几种: emacs           综合性的GNU emacs 编辑环境 nano              一个类似于经典的pico的文本编辑器,内置了一个pi ...

  6. ckeditor富文本编辑器的使用和图片上传,复制粘贴图片上传

    项目开发需要用到在线编辑和图片上传,最终讨论使用ckeditor,原因就是其丰富的API.考虑到最新版本ckeditor5可能不够稳定,我们选择使用ckedtior4.9.2版本.官网链接:ckedi ...

  7. Android富文本编辑器附源码

    Android富文本编辑器附源码 1,源码分析 本软件是Android端创建富文本数据,向服务器发送;安卓端创建数据可以是文字,图片,语音,文件,还可以录音,可以拍照.录音完毕保存的时候应该提交给服务 ...

  8. ckeditor富文本编辑器的使用和图片上传

    项目开发需要用到在线编辑和图片上传,最终讨论使用ckeditor,原因就是其丰富的API.考虑到最新版本ckeditor5可能不够稳定,我们选择使用ckedtior4.9.2版本.官网链接:ckedi ...

  9. 文本编辑器中替换对话框的设计与实现

    文章目录 1 文本编辑器中替换对话框的设计与实现 1 文本编辑器中替换对话框的设计与实现 替换对话框需求分析: 可复用软件部分. 查找文本框中的指定字符串. 替换单个指定字符串. 替换所有指定字符串. ...

最新文章

  1. android网络质量,基于Android的移动通信网络质量信息系统的设计与开发
  2. 127-条件布尔运算符和取反运算符
  3. 数据库课程设计结论_结论:
  4. mybatis新增返回主键值
  5. ef mysql modelfirst_MySQL –EF edmx(Model First)– Sql Server table
  6. 三星成功开发LPDDR5X DRAM 将扩大超高速数据服务市场
  7. 计算机系统-内存的最小存储单元
  8. 第三十五 ASP.NET和Web服务(二)
  9. Oracle的重做日志
  10. 51nod 1135 原根(原根)
  11. 加性噪声--传递概率密度函数=噪声概率密度函数
  12. Effect Size
  13. 更改 Windows 11 上的网络适配器优先级
  14. 超简单方法-彻底解决网页被劫持-自由锁定主页
  15. web 前端签名插件_signature_pad插件实现电子签名功能
  16. 解决TIM版无法修改个人文件夹位置
  17. zha男/女的三种境界
  18. k8s常见报错解决--持续更新
  19. t30服务器的技术性能,DELL PowerEdge T30微塔式服务器 配置参数
  20. Oracle教学辅助.数据库技术发展历史

热门文章

  1. matlab 变长参数,变长参数函数的概念
  2. 输入法注入源码_将注入进行到底:利用Mono注入C#游戏脚本
  3. Error starting userland proxy: listen tcp 0.0.0.0:5601: bind: address already in use
  4. jfinal使用render之后还会继续往下执行代码吗
  5. Game with modulo
  6. Complex Congratulation β
  7. c语言中程序偏离,C语言程序员在编码时容易出错的几个点
  8. 用Socket 打造跨语言跨操作系统的网络MORPG游戏(三)
  9. 《You Only Look Once: Unified, Real-Time Object Detection》YOLO一种实时目标检测方法 阅读笔记(未完成版)
  10. 攻防世界-web-ics-04-从0到1的解题历程writeup