想走?可以!先买票--迭代器模式

1.1 乘车买票,不管你是谁!

售票员检查谁没有买票,把车厢里的人都遍历一遍。

1.2 迭代器模式

        迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。[DP]
        "你想呀,售票员才不管你上来的是人还是物(行李),不管是中国人还是外国人,不管是不是内部员工,甚至哪怕是马上要抓走的小偷,只要是来乘车的乘客,就必须要买票。同样道理,当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式。另外,售票员从车头到车尾来售票,也可以从车尾向车头来售票,也就是说,你需要对聚集有多种方式遍历时,可以考虑用迭代器模式。由于不管乘客是什么,售票员的做法始终是相同的,都是从第一个开始,下一个是谁,是否结束,当前售到哪个人了,这些方法每天他都在做,也就是说,为遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的接口。"

        "哈,本来这个模式还是有点意思的,不过现今来看迭代器模式实用价值远不如学习价值大了,Martin Flower甚至在自己的网站上提出撤销此模式。因为现在高级编程语言如C#、Java等本身已经把这个模式做在语言中了。"
        "哦,是什么?"
        "哈,foreach你熟悉吗?"
        "啊,原来是它,没错没错,它就是不需要知道集合对象是什么,就可以遍历所有的对象的循环工具,非常好用。"
        "另外还有像Iterator接口也是为迭代器模式而准备的。不管如何,学习一下GoF的迭代器模式的基本结构,还是很有学习价值的。研究历史是为了更好地迎接未来。"

1.3 迭代器实现

迭代器模式(Iterator)结构图

package code.chapter20.iterator1;import java.util.ArrayList;public class Test {public static void main(String[] args){System.out.println("**********************************************");		System.out.println("《大话设计模式》代码样例");System.out.println();		ConcreteAggregate bus = new ConcreteAggregate();bus.add("大鸟");bus.add("小菜");bus.add("行李");bus.add("老外");bus.add("公交内部员工");bus.add("小偷");//正序迭代器//Iterator conductor = new ConcreteIterator(bus);//倒序迭代器Iterator conductor = new ConcreteIteratorDesc(bus);conductor.first();while (!conductor.isDone()) {System.out.println(conductor.currentItem() + ",请买车票!");conductor.next();}System.out.println();System.out.println("**********************************************");}
}//聚集抽象类
abstract class Aggregate{//创建迭代器public abstract Iterator createIterator();
}//具体聚集类,继承Aggregate
class ConcreteAggregate extends Aggregate{//声明一个ArrayList泛型变量,用于存放聚合对象private ArrayList<Object> items = new ArrayList<Object>();public Iterator createIterator(){return new ConcreteIterator(this);}//返回聚集总个数public int getCount(){return items.size();}//增加新对象public void add(Object object){items.add(object);}//得到指定索引对象public Object getCurrentItem(int index){return items.get(index);}}//迭代器抽象类
abstract class Iterator{public abstract Object first();         //第一个public abstract Object next();          //下一个public abstract boolean isDone();       //是否到最后public abstract Object currentItem();   //当前对象}//具体迭代器类,继承Iterator
class ConcreteIterator extends Iterator{private ConcreteAggregate aggregate;private int current = 0;//初始化时将具体的聚集对象传入public ConcreteIterator(ConcreteAggregate aggregate){this.aggregate = aggregate;}//得到第一个对象public Object first(){return aggregate.getCurrentItem(0);}//得到下一个对象public Object next() {Object ret = null;current++;if (current < aggregate.getCount()) {ret = aggregate.getCurrentItem(current);}return ret;}//判断当前是否遍历到结尾,到结尾返回truepublic boolean isDone(){return current >= aggregate.getCount() ? true : false;}//返回当前的聚集对象public Object currentItem(){return aggregate.getCurrentItem(current);}
}//具体迭代器类(倒序),继承Iterator
class ConcreteIteratorDesc extends Iterator{private ConcreteAggregate aggregate;private int current = 0;public ConcreteIteratorDesc(ConcreteAggregate aggregate){this.aggregate = aggregate;current = aggregate.getCount()-1;}//第一个对象public Object first(){return aggregate.getCurrentItem(aggregate.getCount()-1);}//下一个对象public Object next() {Object ret = null;current--;if (current >= 0) {ret = aggregate.getCurrentItem(current);}return ret;}//判断当前是否遍历到结尾,到结尾返回truepublic boolean isDone(){return current <0 ? true : false;}//返回当前的聚集对象public Object currentItem(){return aggregate.getCurrentItem(current);}
}

Aggregate聚集抽象类:
ConcreteAggregate具体聚集类:继承Aggregate。
Iterator迭代器抽象类:
ConcreteIterator具体迭代器类:继承Iterator。

        其实售票员完全可以用更多的方式来遍历乘客,比如从最高的到最矮的、从最小到最老、从最靓丽酷毙到最猥琐龌龊。

1.4 Java的迭代器师兄

        "刚才我们也说过,实际使用当中是不需要这么麻烦的,因为Java语言中已经为你准备好了相关接口,你只需去实现就好。"
        Java.util.Iterator支持对集合的简单迭代接口。
        Java.util.ListIterator支持对集合的任意方向上迭代接口。
        "你会发现,这两个接口要比我们刚才写的抽象类Iterator简洁,但可实现的功能却一点不少,这其实也是对GoF的设计改良的结果。"
        "其实具体类实现这两个接口的代码也差别不大,是吗?"
        "是的,区别不大,另外这两个是可以实现泛型的接口,去查Java的API帮助就可以了。"
        "有了这个基础,你再来看你最熟悉的foreach就很简单了。"
        "这里用到了foreach而在编译器里做了些什么呢?其实它做的是下面的工作。"
        "原来foreach就是实现Iterator来实际循环遍历呀。"
        "如果我们想实现刚才的反向遍历。那就用另一个接口实现。"

package code.chapter20.iterator2;import java.util.Iterator;
import java.util.ListIterator;
import java.util.ArrayList;public class Test {public static void main(String[] args){System.out.println("**********************************************");		System.out.println("《大话设计模式》代码样例");System.out.println();		ArrayList<String> bus = new ArrayList<String>();bus.add("大鸟");bus.add("小菜");bus.add("行李");bus.add("老外");bus.add("公交内部员工");bus.add("小偷");System.out.println("foreach遍历:");for(String item : bus){System.out.println(item + ",请买车票!");}System.out.println();System.out.println("Iterator遍历:");Iterator<String> conductor = bus.iterator();while (conductor.hasNext()) {System.out.println(conductor.next() + ",请买车票!");}System.out.println();System.out.println("ListIterator逆向遍历:");ListIterator<String> conductorDesc = bus.listIterator(bus.size());while (conductorDesc.hasPrevious()) {System.out.println(conductorDesc.previous() + ",请买车票!");}System.out.println();System.out.println("**********************************************");}
}public interface Iterator{public boolean hasNext();       //如果迭代具有更多元素,则返回true public Object next();           //返回迭代中的下一个元素}public interface ListIterator{public boolean hasNext();       //如果此列表迭代器在向前遍历列表时具有更多元素,则返回true public Object next();           //返回列表中的下一个元素并前进光标位置public boolean hasPrevious();   //如果此列表迭代器在反向遍历列表时具有更多元素,则返回truepublic Object previous();       //返回列表中的上一个元素并向后移动光标位置}


        "是的,尽管我们不需要显式地引用迭代器,但系统本身还是通过迭代器来实现遍历的。总的来说,迭代器(Iterator)模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明地访问集合内部的数据。迭代器模式在访问数组、集合、列表等数据时,尤其是数据库数据操作时,是非常广泛的应用,但由于它太普遍了,所以各种高级语言都对它进行了封装,所以反而给人感觉此模式本身不太常用了。"

1.5 迭代高手

        "哈哈,看来那个售票员是最了不起的迭代高手,每次有乘客上车他都数数,统计人数,然后再对整车的乘客进行迭代遍历,不放过任何漏网之鱼,啊,应该是逃票之人。"
        "隔行如隔山,任何行业都有技巧和经验,需要多思考、多琢磨,才能做到最好的。"
        "嗯,编程又何尝不是这样,我相信代码没有最好,只有更好,我要继续努力。"

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

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

相关文章

7-23 币值转换

题目链接&#xff1a;7-23 币值转换 一. 题目 1. 题目 2. 输入输出样例 3. 限制 二、代码 1. 代码实现 #include <iostream> #include <string> using namespace std;string numStr[] { // 0-9对应的字符串&#xff08;字符串是方便string&#xff09;"a…

LLM - 大语言模型(LLM) 的 应用技术

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://blog.csdn.net/caroline_wendy/article/details/137503579 大语言模型(LLM) 的应用技术范围非常广泛,即: LangChain:开发框架,专为大型语言模型设计,以提高开发人工智能应用的效率,允许开发者将语言模…

Day16_学点儿JavaEE_实践_基于IDEA2023的简易JavaWeb项目、Tomcat输出乱码解决

0 JavaWeb项目目录 └──JavaWeb├──resources│ └──db.properties├──src│ └──com.sdust.web│ ├──servlet│ │ └──StudentServlet│ ├──pojo│ │ └──Student│ └──util│ └──JDBCUtil├──web│ ├──st…

Nginx健康检查

Nginx健康检查nginx_upstream_check_module nginx健康检查介绍: ​ 主动健康检查&#xff0c;nignx定时主动地去ping后端的服务列表&#xff0c;当发现某服务出现异常时&#xff0c;把该服务从健康列表中移除&#xff0c;当发现某服务恢复时&#xff0c;又能够将该服务加回健…

Day106:代码审计-PHP原生开发篇文件安全上传监控功能定位关键搜索1day挖掘

目录 emlog-文件上传&文件删除 emlog-模板文件上传 emlog-插件文件上传 emlog-任意文件删除 通达OA-文件上传&文件包含 知识点&#xff1a; PHP审计-原生开发-文件上传&文件删除-Emlog PHP审计-原生开发-文件上传&文件包含-通达OA emlog-文件上传&文件…

【高项】信息化发展

目录 1.1 信息与信息化 1.1.1 信息 1.信息的定义 2.信息的特征与质量 1.1.2 信息系统 1.信息系统及其特性 2.信息系统生命周期 1.1.3 信息化 1.信息化内涵 2.信息化体系&#xff08;口诀&#xff1a;上应下技左人右规&#xff0c;中资网&#xff09; 1.2 现代化基础…

集装箱5G智能制造工厂数字孪生可视化平台,推进企业数字化转型

集装箱5G智能制造工厂数字孪生可视化平台&#xff0c;推进企业数字化转型。在当下数字化转型的热潮中&#xff0c;集装箱5G智能制造工厂数字孪生可视化平台成为了推动企业转型升级的重要工具。这一平台将先进的5G技术与智能制造相结合&#xff0c;通过数字孪生技术实现生产过程…

开课通知 | 5月六西格玛绿带培训火热招生

尊敬的各位学员&#xff1a; 天行健管理咨询将于近期开展六西格玛绿带公开课&#xff0c;旨在为广大企业和个人提供专业的六西格玛绿带培训&#xff0c;帮助大家掌握六西格玛绿带的核心知识和技能&#xff0c;提升工作效率和质量。现将相关事宜通知如下&#xff1a; 一、培训时…

工智能图像降噪软件 ON1 NoNoise AI 2024 for Mac激活版

ON1 NoNoise AI 2024 for Mac是一款专为Mac用户设计的先进人工智能图像降噪软件。其核心功能在于能够利用机器学习技术&#xff0c;快速并智能地消除图像中的噪点&#xff0c;无论是亮度噪点还是颜色噪点&#xff0c;都能得到显著的改善。 软件下载&#xff1a;ON1 NoNoise AI …

【AR】使用深度API实现虚实遮挡

遮挡效果 本段描述摘自 https://developers.google.cn/ar/develop/depth 遮挡是深度API的应用之一。 遮挡&#xff08;即准确渲染虚拟物体在现实物体后面&#xff09;对于沉浸式 AR 体验至关重要。 参考下图&#xff0c;假设场景中有一个Andy&#xff0c;用户可能需要放置在包含…

揭秘英特尔AI芯片如何做到比H100训练快40%、推理快50%

英特尔&#xff0c;开始正面硬刚英伟达了。 深夜时分&#xff0c;英特尔CEO帕特基辛格激动展示全新AI芯片Gaudi 3&#xff0c;引领未来科技潮流&#xff0c;开启智能新篇章。 他为什么开心到现场直接蹦迪&#xff1f; 看下Gaudi 3的性能结果&#xff0c;就一目了然了&#xf…

算法打卡day32

今日任务&#xff1a; 1&#xff09;738.单调递增的数字 2&#xff09;968.监控二叉树 738.单调递增的数字 题目链接&#xff1a;738. 单调递增的数字 - 力扣&#xff08;LeetCode&#xff09; 文章讲解&#xff1a;代码随想录 (programmercarl.com) 视频讲解&#xff1a;贪…

初学网络编程

网络编程是指编写能够在网络环境中运行&#xff0c;进行数据通信的程序的过程。它涵盖了从建立网络连接、发送和接收数据&#xff0c;到关闭连接等一系列操作。网络编程是开发网络应用程序的基础&#xff0c;它使得不同的计算机和设备能够通过网络进行数据交换和通信。 三个核…

ELK企业级日志分析系统(elasticsearch+logstash+kibana)

目录 一.ELK概述 1.定义 &#xff08;1&#xff09;ElasticSearch &#xff08;2&#xff09;Kiabana &#xff08;3&#xff09;Logstash &#xff08;4&#xff09;Filebeat 2.filebeat结合logstash带来好处 3.为什么要是用ELK&#xff1f; 4.完整日志系统基本特征 …

Docker学习笔记(一):入门篇,Docker概述、基本组成等,对Docker有一个初步的认识

前言 记录时间 [2024-4-5] 在先前的文章中&#xff0c;笔者进行了Windows系统下YOLOv8模型的简单测试&#xff0c;并由此引发思考&#xff1a;是否能尝试将此模型运行在Linux中呢&#xff1f;又或者&#xff0c;运行在Docker中。关于Docker的学习就这么展开了。 本文便是有关D…

RX8130CE为用户提供带复位延迟和主备电管理的解决方案

实时时钟作为设备的精确时钟来源&#xff0c;其作用如同人的心脏&#xff0c;为设备提供准确稳定的心跳.而便携式设备由于应用场景多变&#xff0c;所以对内部元器件要求也相对较高&#xff0c;这就对作为核心器件的实时时钟模块提出不少挑战。世强代理品牌EPSON实时钟模块产品…

【Linux】开始了解重定向

送给大家一句话&#xff1a; 人真正的名字是&#xff1a;欲望。所以你得知道&#xff0c;消灭恐惧最有效的办法&#xff0c;就是消灭欲望。 – 史铁生 《我与地坛》 开始了解重定向 1 前言2 重定向与缓冲区2.1 文件描述符分配规则2.2 重定向的现象2.3 重定向的理解2.4 缓冲区…

5.6 mybatis之RowBounds分页用法

文章目录 mybatis 中&#xff0c;使用 RowBounds 进行分页&#xff0c;非常方便&#xff0c;不需要在 sql 语句中写 limit&#xff0c;即可完成分页功能。但是由于它是在 sql 查询出所有结果的基础上截取数据的&#xff0c;所以在数据量大的sql中并不适用&#xff0c;它更适合在…

【Python】OPC UA 服务器扫描工具

引言 OPC UA&#xff08;开放平台通信统一架构&#xff09;是一种跨平台的、开放的数据交换标准&#xff0c;广泛用于工业自动化领域。在工业4.0的大背景下&#xff0c;OPC UA服务器在网络中的部署日益增多&#xff0c;如何快速有效地发现这些服务器成为了一个实际需求。本文将…

UI自动化测试重点思考(下)--装饰器/生成器/夹具的使用/描述符的作用/ddt驱动/多线程

UI自动化测试重点思考--装饰器 装饰器装饰器定义装饰器代码示例装饰器的执行如何将装饰器融合到pytest框架里面 生成器创建生成器生成器的定义如何将生成器融合到pytest框架里面 fixture&#xff08;夹具&#xff09;使用pytest fixture 中 scope 参数的详细解释 描述符的总结描…