Java设计模式 (1) —— Iterator迭代器模式

news2025/1/12 18:10:06

        拿到这个话题,首先搞清楚:什么是迭代器?

        大家都学过 for-i 循环,for-i循环的本质就是 通过i++ 或者 i-- ,以实现 从数据的一端 一个一个地遍历数据元素,直到另一端的最后一个元素,将这里 i 的通用作用 抽象化后形成的设计,在设计中就可以叫做迭代器 Iterator;Iterate 在英语中有 "重复说,重复做" 的意思,如:

we iterate through it with foreach.
我们重复做它,通过foreach。(倒过来读也行,我从不求完美。)

        Iterator模式的主要作用就是在数据集合中按照顺序一个一个地遍历集合,我们常说的迭代器,就是这个Iterator;假设我们现在需要做一个容器,底层可以使用链表,也可以使用数组,或者映射,或者其他类型,Anyhow 无论如何,肯定都需要为用户设计一些存取,访问遍历等基本操作。

       在程序设计中,由于底部容器集合的底层实现不同,各自不同的遍历方式,只有容器它自己知道它自己应该如何去遍历,我们无法将这些不同的容器,限制在某一种特定的遍历方式上,对于这种困境,我们就需要做一个统一存取的迭代器接口,让用户不用关系这些容器因为底层原因而造成有各种花里胡哨的的遍历实现,方便用户。

        Iterator 迭代器模式,就是一个专门提供给用户做容器元素访问迭代需求的设计模式。它的优点:

  • 避免了将不同底层的容器遍历访问限制死在某一种实现上的困境。
  • 不用暴露内部结构给用户,增加用户的易用性。

      至于,容器自己怎么遍历,只有容器它自己知道,所以,为了方便用户,我们就要求:让每个容器,自己提供它的迭代器接口,我们用户不用关心它的实现,用就好了。

        迭代器接口代码:

/**
 *  遍历集合容器的接口。
 */
public interface Iterator {
    boolean hasNext();//是否有下一个元素。
    Object next(); //获取元素,并指向下一个元素。
}

        因此我们要求,凡是你觉得你自己是一个集合的类,麻烦您给我们用户提供一个获取迭代器的接口。

/**
 *  表示集合的接口。
 */
public interface AggregateCollection {
    /**
     * 为用户设计的,提供迭代器的方法。
     * @return 返回统一的迭代器。
     */
     Iterator iterator();
}

好了,集合容器 主角上场了。

/**
 * 表示容器集合类 
 * 根据约定,但凡 你觉得你自己要实现一个集合容器,你就需要实现 AggregateCollection 接口。
 * 以提供给用户获取迭代器的方法 iterator()
 */
public class Container implements AggregateCollection {

    private Element[] elements;

    private int size = 0;

    //根据 默认的最大容量capacity 初始化 容器
    public Container(int maxCapacity) {
        this.elements = new Element[maxCapacity];
    }

    //访问容器中每个索引位置的元素。
    public Element getElementAt(int index) {
        return elements[index];
    }

    //Container有效元素,size 的维护机制:每次添加一个元素,元素总数cursor 要 + 1
    public void appendElement(Element element) {
        this.elements[size] = element;
        size++;
    }

    //获取有效元素的个数。
    public int getSize() {
        return size;
    }


    @Override
    public Iterator iterator() {
        return new ContainerIterator(this);
    }

}

        这里提供属于容器的基础方法。为了弱化类之间的耦合,关于如何遍历的内容,专门提取到下面设计的ContainerIterator类中。

/**
 *  容器实现遍历的类。
 */
public class ContainerIterator implements Iterator {

    // 引入容器对象,因为next和hashNext方法,该如何实现,只有container自己知道
    private Container container;

    private int index;

    //初始化容器迭代器。
    public ContainerIterator(Container container){
        this.container = container;
        this.index = 0;
    }


    @Override
    public boolean hasNext() {
        return index < container.getSize();
    }

    @Override
    public Object next() {
        return  container.getElementAt(index++);
    }
}

        容器中的基本元素对象类


/**
 *  容器中的元素对象,加个名字,好遍历显示。
 */
public class Element {
    private String name;

    public Element(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

好了,利用我们的迭代器的设计思想,程序基本已经设计完毕,通过程序测试一下,看看能否达到用户的预期:

站在用户的角度,至于你的集合容器底层如何具体实现,我不管。
凡是你设计的是一个Collection集合容器,你就要给我提供iterate方法,
用户只要拿到你的iterator,
使用的hashNext方法和next方法遍历到你容器中的所有元素。
public class Main {
    public static void main(String[] args) {

        //集合容器Container 中 包含了 iterator 的功能。
        Container container = new Container(6);
        container.appendElement(new Element("Java"));
        container.appendElement(new Element("PHP"));
        container.appendElement(new Element("Javascript"));
        container.appendElement(new Element("Golang"));
        container.appendElement(new Element("CPP"));
        container.appendElement(new Element("Ruby"));

        Iterator it = container.iterator();
        while (it.hasNext()){
            Element element = (Element) it.next();
            System.out.println(element.getName());
        }
    }
}

console 控制台输出:

Java
PHP
Javascript
Golang
CPP
Ruby

        满足需求,OK, that's all !加油,GoGo ! 

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

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

相关文章

【Linux】基础IO —— 深入理解文件系统 | 软硬链接

&#x1f308;欢迎来到Linux专栏~~ 深入理解文件系统 (꒪ꇴ꒪(꒪ꇴ꒪ )&#x1f423;,我是Scort目前状态&#xff1a;大三非科班啃C中&#x1f30d;博客主页&#xff1a;张小姐的猫~江湖背景快上车&#x1f698;&#xff0c;握好方向盘跟我有一起打天下嘞&#xff01;送给自己的…

安全需求和挑战

安全需求和挑战 从风险管理的角度讲&#xff0c;主要就是管理资产、威胁、脆弱性 和防护措施及其相关关系&#xff0c;最终保障云计算平台的持续安全&#xff0c;以及 其所支撑的业务的安全。 云计算平台是在传统 IT技术的基础上&#xff0c;增加了一个虚拟化 层&#xff0c;并…

大数据之——Hive

目录1. Hive 基本概念1.1 什么是 Hive1.2 Hive 的优缺点1.2.1 优点1.2.2 缺点1.3 Hive 架构原理2. Hive 安装2.1 Hive 安装地址2.2Hive 安装部署2.3MySQL 安装2.4 Hive 元数据配置到 MySQL2.4.1 拷贝驱动2.4.2 配置 Metastore 到 MySQL2.4.3 再次启动 Hive2.5 使用元数据服务的…

让学前端不再害怕英语单词(二)

写了本专栏的第一章让学前端不再害怕英语单词&#xff08;一&#xff09;后&#xff0c;反响热度还是比较高的&#xff0c;截止现在已经有20个收藏量了&#xff0c;所以趁热打铁来更第二章 第一章我们简单的介绍了html&#xff0c;css和js的部分高频单词&#xff0c;因为html要…

S32K144的GPIO使用

程序初始化前线使用Components工具对时钟和GPIO进行配置&#xff0c;然后再main函数里面初始化。 时钟配置参考&#xff1a; S32K144之时钟配置 - 明明1109 - 博客园 (cnblogs.com) gpio配置 S32K SDK使用详解之PinSettings组件配置与使用详解(S32K1xx PORT 和GPIO模块)_嵌…

jdk1.8新特性简介

一、引言 jdk1.8出来已经一段时间了&#xff0c;现在1.9也已经出来了&#xff0c;但是很多公司&#xff08;我们公司也一样&#xff09;不太愿意升级到高版本的jdk&#xff0c;主要是有老的项目要维护&#xff0c;还有升级的话配套的框架也要升级&#xff0c;要考虑的细节事情太…

实训素材纯HTML+CSS代码 (教育主题 3页 )

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 家乡旅游景点 | 家乡民生变化 | 介绍自己的家乡 | 我的家乡 | 家乡主题 | HTML期末大学生网页设计作业&#xff0c;Web大学生网页 HTML&#xff1a;结…

SpringMVC具体工作流程(保姆教学)

目录 文章目录[toc]一、SpingMVC的常用组件二、[SpringMVC](https://so.csdn.net/so/search?qSpringMVC&spm1001.2101.3001.7020)的工作流程一、SpingMVC的常用组件 1&#xff09;DispatcherServlet 是一种前端控制器&#xff0c;由框架提供。 作用&#xff1a;统一处理请…

基于Simulink宽带单基地雷达系统仿真(附源码)

目录 一、探索示例 1.1 收发器 1.2 信号处理子系统 1.3 渠道 1.4 目标子系统 二、结果和显示 三、总结 四、程序 本示例演示如何仿真宽带雷达系统。当雷达系统的带宽超过系统中心频率的5%时&#xff0c;通常被认为是宽带的。对于此示例&#xff0c;将使用 10% 的带宽。 …

智慧供应链解决方案-最新全套文件

智慧供应链解决方案-最新全套文件一、建设背景二、建设思路三、建设方案智慧供应链具有以下特点1、高度智能化2、全流程数字化3、信息系统互联互通四、获取 - 智慧供应链全套最新解决方案合集一、建设背景 智慧供应链是结合物联网技术和现代供应链管理的理论、方法和技术&…

ES6 入门教程 16 Reflect 16.1 概述

ES6 入门教程 ECMAScript 6 入门 作者&#xff1a;阮一峰 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录ES6 入门教程16 Reflect16.1 概述16 Reflect 16.1 概述 Reflect对象与Proxy对象一样&#xff0c;也是 ES6 为了操作对象而提供的新 API…

nodejs校园二手交易管理系统vue

本系统的设计主要是为给网上用户提供购物方便&#xff0c;所以应该完成以下目标&#xff1a; (1) 登录、注册。用户要想在交易系统中购买商品&#xff0c;就必须先登录系统。如果不是会员&#xff0c;就必须先注册&#xff0c;然后才能登录系统。 (2) 查找商品。用户可以查找自…

求程序段中++x或者x++的频度,时间复杂度、执行次数

以下程序段中"x"的执行频度&#xff1f; 频度就是执行次数for i:1 to n then;for j:1 to n then;x;i1时 内圈for执行n次...in时 内圈执行n次我的理解&#xff1a;外圈for从1到n&#xff0c;有效循环是n次&#xff0c;外圈每循环一次&#xff0c;内圈循环n次&#…

C语言源代码系列-管理系统之学生籍贯信息

往期文章分享点击跳转>《导航贴》- Unity手册&#xff0c;系统实战学习点击跳转>《导航贴》- Android手册&#xff0c;重温移动开发 &#x1f449;关于作者 众所周知&#xff0c;人生是一个漫长的流程&#xff0c;不断克服困难&#xff0c;不断反思前进的过程。在这个过…

Python 3.11新功能:错误信息回溯

错误信息回溯 长按关注《Python学研大本营》&#xff0c;加入读者群&#xff0c;分享更多精彩 扫码关注《Python学研大本营》&#xff0c;加入读者群&#xff0c;分享更多精彩 Python 3.11于2022 年 10 月 24 日发布。这个最新版本的 Python 速度更快&#xff0c;对用户更友好…

QT源码拾贝0-5(qimage和qpainter)

目录 0 qt源码查看方法 1. qimage.cpp中线程池使用方法 2. qpainter_p.h中SmallStack模板元结构体存放智能指针 3. qpainter.cpp的保存函数&#xff0c;状态对象赋值使用std::exchange函数 4. qpainter.cpp中获得类对象的方法 5. qpainter.cpp中QChar字节操作&…

代码随想录算法训练营三期 day 22 - 二叉树(8)

235. 二叉搜索树的最近公共祖先 原文链接&#xff1a;235. 二叉搜索树的最近公共祖先 题目链接&#xff1a;235. 二叉搜索树的最近公共祖先 在 有序树 里: 从上向下递归遍历&#xff0c;第一次遇到 curcurcur 结点的数值在 p,qp, qp,q 结点对应数值的闭区间中&#xff0c;那么…

内网渗透神器CobaltStrike之Beacon详解(三)

Beacon的种类 HTTP Beacon和HTTPS Beacon 这两个beacon的原理是通过发送http请求与受害主机通信来传达命令, 以此实现控制效果 优点是传输数据快, 缺点时隐蔽性差, 容易被防火墙或内网审计工具拦截 TCP Beacon 自CS4.0版本之后只有反向的TCP Beacon可用, 基于TCP协议的通信…

取证初级案例操作大纲

文章目录**取证初级案例操作大纲**1) 证据文件中有没有存在被删除的Doc文档&#xff1f;如果有的话&#xff0c;请导出并记录文件名及路径&#xff1a;2) 证据文件中有没有存在被删除的图片&#xff1f;如果有的话&#xff0c;请记录文件名及路径&#xff1a;3) 证据文件中哪几…

object类的一些方法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 Object类 输出对象地址 object类里的tostring方法&#xff1a; 正确输出对象里内容 判断俩个对象大小&#xff1a; object类里的equlas方法&#xff1a; 自己实现一…