迭代器 java_Java设计模式8:迭代器模式

迭代器模式

迭代器模式又叫做游标(Cursor)模式,其作用是提供一种方法访问一个容器元素中的各个对象,而又不暴露该对象的内部细节

迭代器模式结构

迭代器模式由以下角色组成:

1、迭代器角色

负责定义访问和遍历元素的接口

2、具体迭代器角色

实现迭代器接口,并要记录遍历中的当前位置

3、容器角色

负责提供创建具体迭代器角色的接口

4、具体容器角色

实现创建具体迭代器角色的接口,这个具体迭代器角色与该容器的结构相关

迭代器模式在JDK中的应用及解读

迭代器模式就不自己写例子了,直接使用JDK中的例子。为什么我们要使用迭代器模式,思考一个问题,假如我有一个ArrayList和一个LinkedList:

912a095f5096968190928ee9c65404db.png

如何去遍历这两个List相信每个人都很清楚:

3753225d03ba512934f564bfa0e7c22c.png

运行结果为:

cda66d78eaa5b7836ae0826c9f26b63d.png

这是因为恰好,我们知道ArrayList和LinkedList的访问方式,有些喜欢研究的人知道ArrayList和LinkedList的内部结构,但如果现在我给你一个HashSet:

01e90e267374d881c0268cc93d842b1e.png

将如何遍历?可能你还以为可以使用类似List的遍历方式,不过很遗憾,HashSet中根本没有提供get方法。

这时候就轮到迭代器出场了,不管是什么数据结构,不管你听过还是没听过,不管你见过还是没见过,只要它实现了Iterable接口,都可以用类似的方式去遍历,我把ArrayList、LinkedList、HashSet的遍历写在一起:

e4792919238f51426ef3e5e211929ca1.png

看一下运行结果:

516208a1fac80eafe5c866bb385150b7.png

看到这就遍历出来ArrayList、LinkedList、HashSet了,以后遇到一个集合,只要实现了iterable接口,也都可以类似这么遍历。这就是开头迭代器模式的定义说的,开发者不需要知道集合中如何去遍历的细节,只管用类似的遍历方法就好了。

Iterable接口和Iterator接口

这两个都是迭代相关的接口,可以这么认为,实现了Iterable接口,则表示某个对象是可被迭代的;Iterator接口相当于是一个迭代器,实现了Iterator接口,等于具体定义了这个可被迭代的对象时如何进行迭代的。参看Iterable接口的定义:

f96a2b9a762532a6200ed45ec3557fd4.png

这样对象就可以使用这个类的迭代器进行迭代了,一般Iterable和Iterator接口都是结合着一起使用的。为什么一定要实现Iterable接口而不直接实现Iterator接口了呢,这个问题我也是在自己写了ArrayList和LinkedList的实现之后才想明白的,这么做确实有道理:

因为Iterator接口的核心方法next()或者hasNext()都是依赖于迭代器的当前迭代位置的。如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据,当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知的。除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。但即使这样,Collection也同时只能存在一个当前迭代位置。而Iterable,每次调用都返回一个从头开始计数的迭代器,多个迭代器时互不干扰。

可能这么解释不是很明白,再解释明白一点,我自己写的一个ArrayList,如果直接实现Iterator接口,那么势必是这么写的:

4b9448e7b23e3b5d24e2de5280c53e86.png

这么问题就来了,如果一个ArrayList实例被多个地方迭代,next()方法、hasNext()直接操作的是ArrayList中的资源,假如我在ArrayList中定义一个迭代位置的变量,那么对于不同调用处,这个迭代变量是共享的,线程A迭代的时候将迭代变量设置成了第5个位置,这时候切换到了线程B,对于线程B来讲,就从第5个位置开始遍历此ArrayList了,根本不是从0开始,如何正确迭代?

实现Iterable接口返回一个Iterator接口的实例就不一样了,我为自己写的ArrayList定义一个内部类:

363056ae497ec91d17edb2036ff537b5.png

每次都返回一个返回一个ArrayListIterator实例出去:

61bff0a316518ab7f352815f94a18cf7.png

这就保证了,即使是多处同时迭代这个ArrayList,依然每处都是从0开始迭代这个ArrayList实例的。

迭代器模式的优缺点

优点

1、简化了便利方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们还可以通过下标来获取,但用户需要在对集合很了解的情况下,才能自行遍历对象(有时即使你了解了集合,还未必能直接遍历,比如上面的HashSet就没有提供get方法)。而引入了迭代器方法后,用户用起来就简单地多了

2、可以供多种遍历方式,比如对于有序列表,可以正向遍历也可以倒序遍历,只要迭代器实现得好

3、封装性好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心

缺点

对于比较简单的遍历(数组或者有序列表),使用迭代器方式遍历较为繁琐而且遍历效率不高,使用迭代器的方式比较适合那些底层以链表形式实现的集合

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/542328.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html二级下拉菜单模板,基于jQuery实现二级下拉菜单效果

本文通过代码实例详细介绍一下简单的二级下拉菜单是如何实现的,当然还有更为复杂的二级菜单,不过先学会如何制作简单的,分享给大家供大家参考,具体内容如下代码如下:下拉菜单nav a{text-decoration:none;}nav>ul>…

给定一个整数判断是否为素数_Ruby程序检查给定数字是否为素数

给定一个整数判断是否为素数检查素数 (Checking prime number) Before getting into writing the code, let us understand what exactly the prime numbers are? So that we could easily design its logic and implement it in the code. Prime numbers are those numbers w…

python 正则findall右斜杠_python中正则表达式的使用

本文将介绍几个最常用的正则符号,以及正则表达式的应用场景。如果说【数学表达式】刻画的是数字的内在规律,那么【正则表达式】则是用来刻画和描述字符串内在规律的表达式。记得刚接触python时学习过slice,replace,split等方法&am…

JavaScript | 用户定义函数的一些示例

1) Design a function, print message and assign the function to a variable and print it like a function 1)设计一个功能&#xff0c;打印消息并将该功能分配给变量&#xff0c;然后像打印功能一样打印 <html lang"en"><head><script>functi…

网易 html5,别再想不开做H5了

写这篇文章的时候网易哒哒《饲养手册》H5刷屏了&#xff0c;但我们依旧不建议品牌做H5。H5作为大众传播工具的时代&#xff0c;已经过去了。尽管去年有很多H5曾经刷屏过&#xff0c;但在当时我们就一直跟朋友说&#xff0c;不要再尝试H5了&#xff0c;性价比根本算不过来&#…

python打开word后再关闭再打开出错_用Python写了个程序调用word,运行完后再手动打开word文档就变慢了,这是为啥?...

公司归档文件比较麻烦&#xff0c;于是用Python写了个程序自动归档&#xff0c;运行无错误。但是运行完后问题就来了&#xff0c;自己手动打开word文档时速度变得奇慢&#xff0c;打开一个文档需要1~2min,请各位同仁帮我看看。下为源代码#归档.pyimport osimport refrom win32c…

编程 mcq_MCQ | 8255 PPI(可编程外围接口)

编程 mcqQuestion 1: How many pins does the 8255 PPI IC contains? 问题1&#xff1a;8255 PPI IC包含多少个引脚&#xff1f; 24 24 20 20 32 32 40 40 Answer: d. 40 答案&#xff1a;d。 40 Question 2: In which mode do all the Ports of the 8255 PPI work as Input…

flex 修改生成html,CSS Flex –动画教程

如果一张图片胜过千言万语 —— 那么动画呢&#xff1f; Flex 无法通过文字或静态图像有效地完全解释。为了巩固你对flex的了解&#xff0c;我制作了这些动画演示。注意 overflow: hidden 行为类型是默认值&#xff0c;因为 flex-wrap 还未设置。为了获得更好的想法&#xff0c…

c#c#继承窗体_C#继承能力问题和解答 套装5

c#c#继承窗体1) Which keyword is used to call a superclass constructor from child class? supertopconstbase Answer & Explanation Correct answer: 4base In C#.NET, base keyword is used to call a base class constructor from a derived class. 1)使用哪个关键字…

python php 网站_python php网站

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里技术人对外发布原创技术内容的最大平台&…

陕西2021高考成绩在哪查询,2021陕西高考成绩查询入口

2021陕西高考成绩查询入口2021-05-13 19:38:37文/张敏有很多同学在关注2021年陕西高考成绩的查询方式&#xff0c;为了方便考生们查询成绩&#xff0c;小编整理了陕西高考成绩查询入口&#xff0c;希望对同学们有帮助。2021陕西高考成绩查询通道高考成绩查询过后应该做什么1、了…

Can’t Activate Reporting Services Service in SharePoint

访问sharepoint的reporing service 的报表的时候莫名其妙的报错&#xff1a; The requested service, http://amatltapp02:32843/1dacf49a2f7a4a6daa8db5768539893f/ReportingWebService.svc could not be activated. See the servers diagnostic trace logs for more informat…

scala python_Scala与Python | 哪种编程语言更好

scala pythonScala is a general-purpose programming language developed by Martin Odersky in 2004. Scala是Martin Odersky在2004年开发的通用编程语言。 Both Scala and Python are general purpose programming that is used in Data Science that supports Object Orie…

查找文件中每行第二个单词_日语单词中的长短音区别在哪里,日语长短音发音有什么规律...

日语单词记忆长短音规律一、如果单词的汉字在中文汉语拼音中是前鼻音&#xff0c;在日语读音中就会带拨音「ん」&#xff1b; 如果单词的汉字在中文汉语拼音中是后鼻音&#xff0c;在日语读音中就会带有长音。例&#xff1a;専门&#xff08;zhuan men&#xff09;&#xff0d;…

SQL Server 执行计划利用统计信息对数据行的预估原理二(为什么复合索引列顺序会影响到执行计划对数据行的预估)...

本文出处&#xff1a;http://www.cnblogs.com/wy123/p/6008477.html 关于统计信息对数据行数做预估&#xff0c;之前写过对非相关列&#xff08;单独或者单独的索引列&#xff09;进行预估时候的算法&#xff0c;参考这里。  今天来写一下统计信息对于复合索引在预估时候的计…

计算机三四级网络技术,全国计算机等级考试四级网络技术论述题真题3

1.(2003年)网络安全策略设计的重要内容之一是&#xff1a;确定当网络安全受到威胁时应采取的应急措施。当我们发现网络受到非法侵入与攻击时&#xff0c;所能采取的行动方案基本上有两种&#xff1a;保护方式与跟踪方式。请根据你对网络安全方面知识的了解&#xff0c;讨论以下…

哈密顿路径_检查图形是否为哈密顿量(哈密顿路径)

哈密顿路径Problem Statement: 问题陈述&#xff1a; Given a graph G. you have to find out that that graph is Hamiltonian or not. 给定图G。 您必须找出该图是否为哈密顿量 。 Example: 例&#xff1a; Input: 输入&#xff1a; Output: 1 输出1 Because here is a …

京东自动下单软件_黄牛软件自动下单秒杀商品 警方用科技手段打击

法制日报全媒体记者 张维定了10个闹钟,也抢不到一瓶茅台&#xff1b;等了很久的iPhone新手机,打开网页就秒没……或许并不是因为你的手速、网速慢,而是黄牛党在用软件和你抢商品。近日,在“净网2019”专项行动中,阿里安全协助江苏省南通市公安局成功打掉了一个制作销售黄牛软件…

Mysql基础之DML语句

增 1 给表的所有字段插入数据 INSERT INTO 表名 VALUES(值1&#xff0c;值2&#xff0c;值3&#xff0c;...&#xff0c;值n)&#xff1b; 2 给表的指定字段插入数据 INSERT INTO 表名(属性1&#xff0c;属性2&#xff0c;...&#xff0c;属性n) VALUES(值1&#xff0c;值2&a…

河南招教考试计算机专业知识,河南教师招聘考试《计算机网络技术基础》知识点归纳七...

河南教师招聘考试《计算机网络技术基础》知识点归纳七1.ADSL是非对称数字用户线路&#xff0c;其下行速率为1.5&#xff5e;8 Mb/s&#xff0c;而上行速率则为16&#xff5e;640 kb/s。在一对铜双绞线上的传送距离可达5km左右&#xff0c;可同时上网打电话&#xff0c;互不影响…