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

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

    //判断当前是否遍历到结尾,到结尾返回true
    public 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;
    }

    //判断当前是否遍历到结尾,到结尾返回true
    public 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();   //如果此列表迭代器在反向遍历列表时具有更多元素,则返回true
    public Object previous();       //返回列表中的上一个元素并向后移动光标位置
    
}



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

1.5 迭代高手

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机导论——C语言001

前言 学习一门语言不是要记住所有这些函数&#xff0c;而是要懂得在哪里找到解决问题的答案 学习英语不是要记住所有单词&#xff0c;而是要懂得查字典&#xff08;因为这样就可以理解单词&#xff0c;并会用单词造句子了&#xff09; 以下侧重于了解输出&#xff08;side eff…

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

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

STM32存储左右互搏 SDIO总线读写SD/MicroSD/TF卡

STM32存储左右互搏 SDIO总线读写SD/MicroSD/TF卡 SD/MicroSD/TF卡是基于FLASH的一种常见非易失存储单元&#xff0c;由接口协议电路和FLASH构成。市面上由不同尺寸和不同容量的卡&#xff0c;手机领域用的TF卡实际就是MicroSD卡&#xff0c;尺寸比SD卡小&#xff0c;而电路和协…

Acrobat Pro DC 2023 for mac直装激活版 pdf编辑处理工具

Acrobat Pro DC 2023 for Mac是一款功能强大的PDF编辑器&#xff0c;为用户提供了全面且高效的PDF处理体验。 软件下载&#xff1a;Acrobat Pro DC 2023 for mac直装激活版下载 首先&#xff0c;它支持用户从现有文档创建PDF&#xff0c;或者将其他文件格式如图片、网页等轻松转…

win11wifi总掉线怎么办,win11连接wifi频繁掉线

很多网友纷纷用上了win11系统,但是由于对win11系统的不熟悉,因此常常在使用的过程中遇到很多问题。几天前,有网友反馈,系统自从升级win11以后,电脑连接wifi上网时,总是会掉线。一般出现此问题,可能是网络没有播报或开启了无线网卡节能模式导致的。那么,win11wifi总掉线…

【Linux】开始了解重定向

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

Chatgpt掘金之旅—有爱AI商业实战篇|在线课程业务|(十五)

演示站点&#xff1a; https://ai.uaai.cn 对话模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 一、AI技术创业在线课程业务有哪些机会&#xff1f; 人工智能&#xff08;AI&#xff09;技术作为当今科技创新的前沿领域&#xff0c;为创业者提供了广阔的机会和挑战。随着…

前端vue2中的excel导出功能-file-saver,xlsx,xlsx-style的使用

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 今天遇到了一个技术点.前端的excel的纯导出功能,不和后端交互,只用前端导出数据 整体架构流程 vue2 element-ui 技术名词解释 在网上看了很多帖子,最后我选择了xlsx , file-saver , xlsx-style 这个三个插件完成…

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

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

第十三届蓝桥杯省赛大学B组编程题(c++)

D.刷题统计 二分(AC): 注意:二分时右边界 right 的确定 #include<iostream> using namespace std; long long a,b,n; bool check(long long x){long long tx/7;x%7;long long temp0;if(x<5) tempx*a;else temp5*a(x-5)*b;long long cntt*(5*a2*b)temp;return cnt&g…

第十一届蓝桥杯大赛第二场省赛试题 CC++ 研究生组-七段码

#include<iostream> using namespace std; const int N 10, M 7; int e[N][N] {0}, f[N], open[N];//e[i][j]表示i和j之间是否连通&#xff1b;f[i]表示结点i的父节点&#xff1b;open[i] 1表示结点i打开&#xff0c;0表示关闭 long long ans 0;int find(int x){if(…

网络原理(应用层、传输层)

文章目录 一、应用层1.1 自定义协议1.2 通用协议XMLJSONprotobuf 1.3 DNS 域名解析系统 二、传输层2.1 UDP协议2.2 TCP协议协议端格式及解析可靠性机制确认应答超时重传连接管理&#xff08;三次握手&#xff0c;四次挥手&#xff09;流量控制拥塞控制 效率机制滑动窗口延迟应答…

Anzo Capital 荣膺2024年最值得信赖经纪商大奖

Anzo Capital 表示&#xff1a;“自Anzo Capital品牌诞生起&#xff0c;始终坚持以客户为中心&#xff0c;不断提升产品力和品牌力&#xff0c;致力于成为世界上最值得信赖和推荐的经纪商。而从2015年成立至今&#xff0c;已经服务全球40多个国家&#xff0c;超过34.8万个客户…

财富池指标公式--通达信筹码底部指标公式源码

很多交易软件上都会提供筹码分布可查看主力资金动向&#xff0c;比如说&#xff1a;同花顺软件的筹码分布功能上&#xff1a;红色筹码代表低于收盘价的获利筹码&#xff0c;蓝色筹码表示高于收盘价的套牢盘筹码。 在手机上或电脑端&#xff0c;可将光标移至相应的价位&#xf…

(洛谷P34060):海底高铁—->差分数组,贪心思想

海底高铁 题目描述 该铁路经过 N N N 个城市&#xff0c;每个城市都有一个站。不过&#xff0c;由于各个城市之间不能协调好&#xff0c;于是乘车每经过两个相邻的城市之间&#xff08;方向不限&#xff09;&#xff0c;必须单独购买这一小段的车票。第 i i i 段铁路连接了…

【Web】CTFSHOW-ThinkPHP5-6反序列化刷题记录(全)

目录 web611 web612 web613-622 web623 web624-626 纯记录exp&#xff0c;链子不作赘述 web611 具体分析&#xff1a; ThinkPHP-Vuln/ThinkPHP5/ThinkPHP5.1.X反序列化利用链.md at master Mochazz/ThinkPHP-Vuln GitHub 题目直接给了反序列化入口 exp: <?ph…

实验9 内置对象application

一、实验目的 掌握怎样在JSP中使用内置对象application 二、实验项目内容&#xff08;实验题目&#xff09; 编写代码&#xff0c;掌握application的用法。【参考课本例题4-16 留言板 】 三、源代码以及执行结果截图&#xff1a; example4_16.jsp <% page language"…

【2024年认证杯】A题详细思路+数据(来源)+成品论文+模型代码

2024年认证杯A题 解题思路 ⭐⭐第一问题分析第二问题分析第三问题分析 数据与数据来源指标解释数据来源 参考论文python/ matlab 代码 解题思路 ⭐⭐ 这个题目要求我们围绕人造保暖纤维的保暖能力进行建模&#xff0c;并解决三个具体问题。 第一问题分析 第一问题要求建立一…

【C 数据结构】循环链表

文章目录 【 1. 基本原理 】【 2. 循环链表的创建 】2.1 循环链表结点设计2.2 循环单链表初始化 【 3. 循环链表的 插入 】【 4. 循环单链表的 删除操作 】【 5. 循环单链表的遍历 】【 6. 实例 - 循环链表的 增删查改 】【 7. 双向循环链表 】 【 1. 基本原理 】 对于单链表以…

【嵌入式学习】ARM day04.11

一、思维导图 二、练习 实现三个灯闪烁 汇编代码 .text .global _start _start: 使能GPIOE和F时钟LDR r0,0x50000A28LDR r1,[R0]ORR R1,R1,#(0X3<<4)STR R1,[R0]配置GPIOE和F的MODER寄存器LDR r0,0x50006000 GPIOELDR R1,0X50007000 G…