迭代器模式的理解和实践

引言

        在软件开发中,我们经常需要遍历容器对象(如数组、列表、集合等)中的元素。如果每个容器对象都实现自己的遍历算法,那么代码将会变得冗余且难以维护。为了解决这个问题,迭代器模式应运而生。迭代器模式是一种行为型设计模式,它提供了一种统一的方法来访问容器对象中的元素,而无需暴露容器的内部结构。本文将详细讲解迭代器模式的概念、原理及其在Java中的实践应用。

 

一、迭代器模式概述

1.1 定义

        迭代器模式(Iterator Pattern)又称为游标模式,是一种行为型设计模式。它提供了一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。迭代器模式使得用户可以通过一致的接口访问不同聚合对象中的元素,而无需了解聚合对象的内部结构。

1.2 结构

        迭代器模式主要包含以下角色:

  • 迭代器(Iterator):定义访问和遍历元素的接口,通常包含 hasNext() 和 next() 方法。
  • 具体迭代器(ConcreteIterator):实现迭代器接口,并要记录遍历中的当前位置。
  • 聚合(Aggregate):也称为容器,负责提供创建具体迭代器角色的接口,通常是一个接口或抽象类,包含一个 iterator() 方法。
  • 具体聚合(ConcreteAggregate):实现聚合接口,返回具体的迭代器实例。
  • 客户端(Client):使用迭代器遍历聚合对象中的元素。

1.3 原理

        迭代器模式的原理是将集合对象的遍历逻辑从集合类中分离出来,封装在独立的迭代器类中。这样,客户端可以通过迭代器接口访问集合中的元素,而无需知道集合的内部结构。同时,迭代器类可以根据不同的集合实现不同的遍历算法,从而提供灵活的遍历方式。

二、迭代器模式的优点和缺点

2.1 优点

  • 简化集合接口:迭代器承担了遍历集合的职责,使得集合接口更加简洁,只关注元素的添加、删除等操作。
  • 支持多种遍历方式:可以为不同的需求定制不同的迭代器,如正向迭代器、反向迭代器、过滤器迭代器等。
  • 统一访问方式:无论集合结构如何变化,迭代器为访问提供一致的接口,用户无需改变遍历代码。
  • 提高代码复用性:迭代器模式使得相同的遍历算法可以在不同的集合上重复使用。

2.2 缺点

  • 性能问题:创建迭代器可能带来额外的资源消耗,尤其是在集合较小或遍历操作较简单时。
  • 复杂度增加:对于简单的遍历需求,直接使用循环可能更简单明了。引入迭代器模式可能会增加代码的复杂度。
  • 迭代器失效:如果集合在迭代过程中被修改(如添加、删除元素),可能会导致迭代器失效。解决策略可能包括在迭代器失效时抛出异常,或在集合类中进行操作时自动更新迭代器。

三、迭代器模式的实践

        下面我们以一个简单的书籍集合为例,演示如何使用迭代器模式遍历集合中的元素。

3.1 定义书籍类和书籍集合

        首先,我们定义一个书籍类 Book 和一个书籍集合接口 BookShelf。书籍集合接口包含一个 iterator() 方法,用于返回迭代器实例。

// 书籍类
public class Book {
    private String name;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

// 书籍集合接口
public interface BookShelf {
    Iterator<Book> iterator();
}


3.2 实现具体书籍集合和迭代器

        接下来,我们实现一个具体的书籍集合 ConcreteBookShelf 和一个具体的迭代器 BookShelfIterator

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

// 具体书籍集合
public class ConcreteBookShelf implements BookShelf {
    private List<Book> books = new ArrayList<>();

    public void addBook(Book book) {
        this.books.add(book);
    }

    public List<Book> getBooks() {
        return books;
    }

    @Override
    public Iterator<Book> iterator() {
        return new BookShelfIterator(this);
    }
}

// 具体迭代器
public class BookShelfIterator implements Iterator<Book> {
    private ConcreteBookShelf bookShelf;
    private int index;

    public BookShelfIterator(ConcreteBookShelf bookShelf) {
        this.bookShelf = bookShelf;
        this.index = 0;
    }

    @Override
    public boolean hasNext() {
        return index < bookShelf.getBooks().size();
    }

    @Override
    public Book next() {
        if (hasNext()) {
            return bookShelf.getBooks().get(index++);
        }
        throw new RuntimeException("No more elements in the iteration");
    }
}


3.3 客户端代码

        最后,我们编写客户端代码,使用迭代器遍历书籍集合中的元素。

public class Client {
    public static void main(String[] args) {
        ConcreteBookShelf bookShelf = new ConcreteBookShelf();
        bookShelf.addBook(new Book("Around the World in 80 Days"));
        bookShelf.addBook(new Book("Bible"));
        bookShelf.addBook(new Book("Cinderella"));
        bookShelf.addBook(new Book("Daddy-Long-Legs"));
        bookShelf.addBook(new Book("White-Rich-Beautiful"));

        Iterator<Book> iterator = bookShelf.iterator();
        while (iterator.hasNext()) {
            Book book = iterator.next();
            System.out.println(book.getName());
        }
    }
}


3.4 运行结果

        运行客户端代码,输出结果为:

Around the World in 80 Days
Bible
Cinderella
Daddy-Long-Legs
White-Rich-Beautiful


四、迭代器模式的应用场景

        迭代器模式在实际开发中有很多应用场景,以下是一些常见的例子:

  • 集合类:如Java中的List、Set、Map等集合类都实现了迭代器模式,提供了统一的遍历接口。
  • 菜单系统:在GUI应用程序中,菜单项通常存储在一个集合中。使用迭代器模式可以方便地遍历菜单项,并根据需要执行相应的操作。
  • 文件系统:在文件系统中,文件和目录通常组织成一个树状结构。使用迭代器模式可以遍历文件系统树,查找文件或目录。
  • 数据库查询结果:数据库查询结果通常返回一个结果集对象。使用迭代器模式可以遍历结果集中的每一行数据,并进行处理。

总结

        迭代器模式是一种强大的设计模式,它提供了一种统一的方法来访问容器对象中的元素,而无需暴露容器的内部结构。通过将遍历逻辑封装在独立的迭代器类中,迭代器模式简化了集合接口,支持多种遍历方式,并提高了代码的复用性。同时,迭代器模式也存在一些缺点,如性能问题和复杂度增加等。在实际开发中,我们需要根据具体需求权衡利弊,选择合适的设计模式来实现功能。希望本文能帮助你理解迭代器模式,并通过具体的Java代码示例掌握其实现方法。

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

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

相关文章

STM32一keil5更换芯片后报错问题的解决。

目录 一、STM32型号认识二、报错问题三、常用的启动配置文件四、问题解决 一、STM32型号认识 二、报错问题 当我们在原来工程下修改芯片时&#xff0c;原本可以编译通过的代码突然很多报错。如下所示&#xff0c;这是因为我们的启动文件配置错误。对于不同型号的芯片其flash容量…

人工智能-自动驾驶领域

目录 引言自动驾驶与人工智能的结合为什么自动驾驶领域适合发表文章博雅智信的自动驾驶辅导服务结语 引言 自动驾驶技术的崛起是当代交通行业的一场革命。通过结合先进的人工智能算法、传感器技术与计算机视觉&#xff0c;自动驾驶不仅推动了技术的进步&#xff0c;也使得未来…

c++数据结构算法复习基础--11--高级排序算法-快速排序-归并排序-堆排序

高阶排序 1、快速排序 冒泡排序的升级算法 每次选择一个基准数&#xff0c;把小于基准数的放到基准数的左边&#xff0c;把大于基准数的放到基准数的右边&#xff0c;采用 “ 分治算法 ”处理剩余元素&#xff0c;直到整个序列变为有序序列。 最好和平均的复杂度&#xff1a…

修改MySQL存储路径

1.查看原路径 show variables like ‘%datadir%’; 2.停止MYSQL 以管理员身份运行命令提示符 net stop MySQL84 在服务中直接停止MySQL 3.编辑配置文件 可能会遇到无权限修改&#xff0c;可以先修改my.ini的权限。可以通过&#xff1a;右键my.ini → 属性 → 安全→ 编辑 …

微信小程序报错:http://159.75.169.224:7300不在以下 request 合法域名列表中,请参考文档

要解决此问题&#xff0c;需打开微信小程序开发者工具进行设置&#xff0c;打开详情-本地设置重新运行&#xff0c;该报错就没有啦

深入浅出:使用 Gin 框架生成 API 文档

深入浅出&#xff1a;使用 Gin 框架生成 API 文档 在现代 Web 开发中&#xff0c;API 文档是开发者之间沟通的重要桥梁。它不仅帮助前端开发者理解如何调用后端接口&#xff0c;还为测试人员和运维人员提供了宝贵的参考。对于 Go 语言开发者来说&#xff0c;Gin 是一个非常流行…

【 工具变量】IPCC碳排放因子数据测算表

一、数据简介&#xff1a; 排放因子法是IPCC提出的一种碳排放估算方法&#xff0c;也是目前适用范围最广、应用最为普遍的方法。将各类能源消耗的实物统计量转变为标准统计量&#xff0c;再乘以各自的碳排放因子&#xff0c;加总之后就可以得到碳排放总量。如果按照ISO14064标…

兔子的寿命有多长?

在宠物的世界里&#xff0c;兔子以其灵动的身姿、柔软的皮毛和温顺的性格深受人们喜爱。然而&#xff0c;当我们满心欢喜地将兔子迎进家门时&#xff0c;可曾想过它们能陪伴我们多久&#xff1f;兔子的寿命&#xff0c;是一个值得深入探讨的话题&#xff0c;它不仅关乎生命的时…

echarts地图立体效果,echarts地图点击事件,echarts地图自定义自定义tooltip

一.地图立体效果 方法1:两层地图叠加 实现原理:geo数组中放入两个地图对象,通过修改zlevel属性以及top,left,right,bottom形成视觉差 配置项参考如下代码: geo: [{zlevel: 2,top: 96,map: map,itemStyle: {color: #091A51ee,opacity: 1,borderWidth: 2,borderColor: #16BAFA…

游戏发布AppStore平台

首先&#xff0c;要注册一个开发者账号。这里不多说了&#xff0c;下载官方app“Developer”&#xff0c;然后买个能发布的账号&#xff0c;个人&#x1f4b2;99的就行。&#xff08;其实还有点麻烦&#xff0c;我的好像是人脸识别后出问题了&#xff0c;反正遇到问题找苹果官方…

​​​​​​​移远通信基于高通平台发布可集成边缘计算功能的5G MBB解决方案

在5G技术与人工智能深度融合的背景下&#xff0c;各行各业正迎来前所未有的创新机遇。为了加速5G移动宽带&#xff08;MBB&#xff09;行业向智能化转型&#xff0c;并简化边缘计算应用的开发流程&#xff0c;移远通信近期隆重推出了基于骁龙5G调制解调器及射频系统打造&#x…

flinkSql 将流和表的互相转换

流——>表 方式一 方式二 方式一&#xff1a;写sql DataStreamSource<String> source env.socketTextStream("localhost", 8881); // 表名&#xff0c;流&#xff0c;字段名称 tableEnv.createTemporaryView("t_1",source&#xff0c;$("…

React性能优化

三个可以优化的地方 避免过度多次渲染 组件会在以下情况下重新渲染 注意&#xff1a;例如组件组合的形式&#xff0c;<Test><Counter></Counter></Test>,即使Test发生了重新渲染&#xff0c;Counter也不会重新渲染。另外使用React这样的库或框架时&a…

分布式事务的前世今生-纯理论

一个可用的复杂的系统总是从可用的简单系统进化而来。反过来这句话也正确: 从零开始设计的复杂的系统从来都用不了&#xff0c;也没办法让它变的可用。 --John Gal 《系统学》 1975 1. 事务的概念 百科&#xff1a; 事务&#xff08;Transaction&#xff09;&#xff0c;一般是…

k8s-编写CSI插件(3)

1、概述 在 Kubernetes 中&#xff0c;存储插件的开发主要有以下几种方式&#xff1a; CSI插件&#xff1a;Container Storage Interface (CSI) 是 Kubernetes 的标准插件接口&#xff0c;是全新的插件方案&#xff0c;插件和驱动调用通过grpc协议&#xff0c;功能丰富&#x…

Linux系统:网络

目录 一、网络协议 1.网络协议概念 2.协议分层 3.OSI七层模型和TCP/IP五层&#xff08;或四层&#xff09;模型 4.为什么要有网络协议&#xff1f; 5.网络通信协议的原理 二、网络传输的基本流程 1.局域网的网络传输流程 1.MAC地址 2.局域网通信原理&#xff08;以太网…

电子应用设计方案-45:智能火锅系统方案设计

智能火锅系统方案设计 一、引言 随着人们生活水平的提高和对饮食体验的追求&#xff0c;智能火锅系统应运而生。本方案旨在设计一款集智能化控制、高效加热、安全保障和个性化体验于一体的智能火锅系统。 二、系统概述 1. 系统目标 - 实现精准的温度控制&#xff0c;满足不同…

论文概览 |《Urban Analytics and City Science》2023.03 Vol.50 Issue.3

本次给大家整理的是《Environment and Planning B: Urban Analytics and City Science》杂志2023年3月第50卷第3期的论文的题目和摘要&#xff0c;一共包括18篇SCI论文&#xff01; 论文1 A new kind of search 一种新型的搜索 【摘要】 ChatGPT (2022) was first launched o…

jwt简介和在go中的简单使用

什么是 JSON Web 令牌&#xff1f; JSON Web 令牌 &#xff08;JWT&#xff09; 是一种开放标准 &#xff08;RFC 7519&#xff09;&#xff0c;它定义了一种紧凑且自包含的方式&#xff0c;用于将信息作为 JSON 对象在各方之间安全地传输。此信息是经过数字签名的&#xff0c…

机器学习详解(3):线性回归之代码详解

文章目录 1 数据预处理2 构建线性回归模型并绘制回归线初始化方法前向传播&#xff1a;forward_propagation代价函数&#xff1a;cost_function反向传播&#xff1a;backward_propagation参数更新&#xff1a;update_parameters训练方法&#xff1a;train代码运行结果 3 使用Py…