实现文本编辑器的设计与实现_ArrayList实现分析(三)——迭代器的实现
![](/assets/blank.gif)
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实现分析(三)——迭代器的实现相关推荐
- java文本编辑器课程设计报告_java课程设计报告 心得体会——计算器、文本编辑器.doc...
java课程设计报告 心得体会--计算器.文本编辑器.doc 还剩 24页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价低环保! 内 ...
- java 课程设计文本编辑器,JAVA课程设计--文本编辑器
JAVA课程设计--文本编辑器 Java 语言课程期末作业 1 Java 语言课程期末作业 题 目 第 8 题,文本编辑器 学 院 计算机学院 专 业 计算机科学与技术 班 别 学 号 姓 名 201 ...
- python多功能文本编辑器_多功能文本编辑器(EditPad Pro)
EditPad Pro 是一款多功能文本编辑器,设计的目标就是在保持程序小巧简洁的同时,提供所有基础编辑功能.EditPad Pro 可以在 Windows 98.Me.NT4.2000.XP.Vis ...
- c#实现类似Sublime Text文本编辑器、电脑屏幕画板
一.前言 需要源码请留言,环境配置请留言,项目运行时报错请留言 结课设计,使用vs2017开发winForm窗体应用程序,包括简单的sublime text文本编辑器.屏幕画板程序. 文本编辑器:设计 ...
- Ubuntu下几种常用的文本编辑器
常见的基于控制台的文本编辑器有以下几种: emacs 综合性的GNU emacs 编辑环境 nano 一个类似于经典的pico的文本编辑器,内置了一个pi ...
- ckeditor富文本编辑器的使用和图片上传,复制粘贴图片上传
项目开发需要用到在线编辑和图片上传,最终讨论使用ckeditor,原因就是其丰富的API.考虑到最新版本ckeditor5可能不够稳定,我们选择使用ckedtior4.9.2版本.官网链接:ckedi ...
- Android富文本编辑器附源码
Android富文本编辑器附源码 1,源码分析 本软件是Android端创建富文本数据,向服务器发送;安卓端创建数据可以是文字,图片,语音,文件,还可以录音,可以拍照.录音完毕保存的时候应该提交给服务 ...
- ckeditor富文本编辑器的使用和图片上传
项目开发需要用到在线编辑和图片上传,最终讨论使用ckeditor,原因就是其丰富的API.考虑到最新版本ckeditor5可能不够稳定,我们选择使用ckedtior4.9.2版本.官网链接:ckedi ...
- 文本编辑器中替换对话框的设计与实现
文章目录 1 文本编辑器中替换对话框的设计与实现 1 文本编辑器中替换对话框的设计与实现 替换对话框需求分析: 可复用软件部分. 查找文本框中的指定字符串. 替换单个指定字符串. 替换所有指定字符串. ...
最新文章
- android网络质量,基于Android的移动通信网络质量信息系统的设计与开发
- 127-条件布尔运算符和取反运算符
- 数据库课程设计结论_结论:
- mybatis新增返回主键值
- ef mysql modelfirst_MySQL –EF edmx(Model First)– Sql Server table
- 三星成功开发LPDDR5X DRAM 将扩大超高速数据服务市场
- 计算机系统-内存的最小存储单元
- 第三十五 ASP.NET和Web服务(二)
- Oracle的重做日志
- 51nod 1135 原根(原根)
- 加性噪声--传递概率密度函数=噪声概率密度函数
- Effect Size
- 更改 Windows 11 上的网络适配器优先级
- 超简单方法-彻底解决网页被劫持-自由锁定主页
- web 前端签名插件_signature_pad插件实现电子签名功能
- 解决TIM版无法修改个人文件夹位置
- zha男/女的三种境界
- k8s常见报错解决--持续更新
- t30服务器的技术性能,DELL PowerEdge T30微塔式服务器 配置参数
- Oracle教学辅助.数据库技术发展历史
热门文章
- matlab 变长参数,变长参数函数的概念
- 输入法注入源码_将注入进行到底:利用Mono注入C#游戏脚本
- Error starting userland proxy: listen tcp 0.0.0.0:5601: bind: address already in use
- jfinal使用render之后还会继续往下执行代码吗
- Game with modulo
- Complex Congratulation β
- c语言中程序偏离,C语言程序员在编码时容易出错的几个点
- 用Socket 打造跨语言跨操作系统的网络MORPG游戏(三)
- 《You Only Look Once: Unified, Real-Time Object Detection》YOLO一种实时目标检测方法 阅读笔记(未完成版)
- 攻防世界-web-ics-04-从0到1的解题历程writeup