迭代器模式的理解和實踐

引言

????????在軟件開發中,我們經常需要遍歷容器對象(如數組、列表、集合等)中的元素。如果每個容器對象都實現自己的遍歷算法,那么代碼將會變得冗余且難以維護。為了解決這個問題,迭代器模式應運而生。迭代器模式是一種行為型設計模式,它提供了一種統一的方法來訪問容器對象中的元素,而無需暴露容器的內部結構。本文將詳細講解迭代器模式的概念、原理及其在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;}@Overridepublic 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;}@Overridepublic boolean hasNext() {return index < bookShelf.getBooks().size();}@Overridepublic 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代碼示例掌握其實現方法。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/62560.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62560.shtml
英文地址,請注明出處:http://en.pswp.cn/web/62560.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

TS2339: Property ‘value‘ does not exist on type ‘MessageBoxData‘.

1、源代碼 <template><el-dialog:visible"visible":before-close"handleClose":close-on-click-modal"false"title"邀請碼"width"1200px"append-to-bodydestroy-on-close><div class"invite-code-wrap…

ubuntu防火墻(三)——firewalld使用與講解

本文是Linux下&#xff0c;用ufw實現端口關閉、流量控制(二) firewalld使用方式 firewalld 是一個動態管理防火墻的工具&#xff0c;主要用于 Linux 系統&#xff08;包括 Ubuntu 和 CentOS 等&#xff09;。它提供了一個基于區域&#xff08;zones&#xff09;和服務&#x…

Windows 安裝配置 RabbitMQ 詳解

博主介紹&#xff1a; 計算機科班人&#xff0c;全棧工程師&#xff0c;掌握C、C#、Java、Python、Android等主流編程語言&#xff0c;同時也熟練掌握mysql、oracle、sqlserver等主流數據庫&#xff0c;能夠為大家提供全方位的技術支持和交流。 工作五年&#xff0c;具有豐富的…

R語言的數據結構--矩陣

【圖書推薦】《R語言醫學數據分析實踐》-CSDN博客 《R語言醫學數據分析實踐 李丹 宋立桓 蔡偉祺 清華大學出版社9787302673484》【摘要 書評 試讀】- 京東圖書 (jd.com) R語言醫學數據分析實踐-R語言的數據結構-CSDN博客 矩陣是一個二維數組&#xff0c;矩陣中的元素都具有相…

JAVA基礎學習筆記_反射+動態代理

文章目錄 反射獲取class對象的三種方式獲取構造方法獲取成員變量獲取成員方法反射的作用 動態代理 反射 允許對成員變量\成員方法\構造方法的信息進行編程訪問 把類內的信息扒的干干凈凈,獲取解剖 獲取從class字節碼文件中獲取 獲取class對象的三種方式 public static void …

微信小程序一鍵復制功能

wx.setClipboardData(Object object) 設置系統剪貼板的內容。調用成功后&#xff0c;會彈出 toast 提示"內容已復制"&#xff0c;持續 1.5s wx.setClipboardData({data: 你需要復制的內容,success (res) {wx.getClipboardData({success (res) {console.log(res.dat…

【Python網絡爬蟲 常見問題匯總】

目錄 1. 爬取圖片出現403解決辦法&#xff1a;設置請求頭中的Referer字段 2.關于干壞事的問題后續不定期更新 歡迎共同探討學習進步 1. 爬取圖片出現403 問題出自案例9&#xff0c;已解決。 【Python網絡爬蟲筆記】9- 抓取優美圖庫高清壁紙 當在爬取圖庫圖片時遇到 403 錯誤…

Linux: docker: 怎么修改 proc下的文件內容?

文章目錄 參考問題方法 1:在宿主機上修改參數方法 2:啟動容器時掛載 /proc 為可寫方法 3:通過 Kubernetes 調整配置方法 4:構建特權容器參考 https://docs.docker.com/security/for-admins/hardened-desktop/enhanced-container-isolation/features-benefits/#procfs–sys…

分布式 分布式事務 總結

前言 相關系列 《分布式 & 目錄》《分布式 & 分布式事務 & 總結》《分布式 & 分布式事務 & 問題》 分布式事務 所謂分布式事務是指操作范圍籠罩多個不同節點的事務。例如對于訂單節點&庫存節點而言&#xff0c;一次完整的交易需要同時調動兩個節…

STM32+模擬或硬件IIC+SHT20驅動問題:接上拉電阻、BUSY死鎖?

主要問題&#xff1a; 1&#xff0c;使用STM32F103C8T6&#xff0c;模擬IIC&#xff0c;SCL和SDA口配置為推挽輸出上拉&#xff0c;主要是SDA腳&#xff0c;每次都要輸出輸入模式重新配置&#xff0c;雖然也能通信&#xff0c;但不穩定&#xff0c;出錯率大&#xff1b; 2&…

【工業機器視覺】基于深度學習的水表盤讀數識別(3-數據標注與轉換)

【工業機器視覺】基于深度學習的儀表盤識讀&#xff08;2&#xff09;-CSDN博客 數據標注 標注擴展 Labelme 和 LabelImg 都是用于創建機器學習和計算機視覺項目所需標注數據的工具。它們都允許用戶通過圖形界面手動標注圖像&#xff0c;但各自有其特點和適用場景。 Labelme…

靜態路由與交換機配置實驗

1.建立網絡拓撲 添加2臺計算機&#xff0c;標簽名為PC0、PC1&#xff1b;添加2臺二層交換機2960&#xff0c;標簽名為S0、S1&#xff1b;添加2臺路由器2811&#xff0c;標簽名為R0、R1&#xff1b;交換機劃分的VLAN及端口根據如下拓撲圖&#xff0c;使用直通線、DCE串口線連接…

【Spark】Spark Join類型及Join實現方式

Spark Join類型 1. Inner Join (內連接) 示例&#xff1a;val result df1.join(df2, df1("id") df2("id"), "inner")執行邏輯&#xff1a;只返回那些在兩個表中都有匹配的行。 2. Left Join (左外連接) 示例&#xff1a;val result df1.jo…

socket UDP 環路回顯的服務端

基于socket通訊的方式&#xff0c;無論用http或者udp或者自定義的協議&#xff0c;程序結構都是類似的。這個以UDP協議為例簡要說明。 #include <stdio.h> // 標準輸入輸出庫 #include <sys/types.h> // 提供了一些數據類型&#xff0c;如ssize_t #include <sy…

Linux:network:添加ip的時候自動添加一個本地路由

文章目錄 問題問題 最近在看一個路由的問題,順便看內核代碼,發現在添加IP的時候,內核會自動添加一個local route。 net/ipv4/devinet.c inet_rtm_newaddr->__inet_insert_ifa /* Send message first, then call notifier.Notifier will trigger FIB update, so thatlis…

Magnet Player:一款基于Web的磁力鏈媒體播放器

Magnet Player&#xff1a;一款基于Web的磁力鏈媒體播放器 項目地址:https://gitcode.com/gh_mirrors/ma/magnet-player 是一個創新的開源項目&#xff0c;它允許用戶直接在瀏覽器中播放磁力鏈&#xff08;Magnet URI&#xff09;內容&#xff0c;無需下載或安裝任何桌面應用…

php:完整部署Grid++Report到php項目,并實現模板打印

一、下載Grid++Report軟件 路徑:開發者安裝包下載 - 銳浪報表工具 二、 安裝軟件 1、對下載的壓縮包運行內部的exe文件 2、選擇語言 3、 完成安裝引導 下一步即可 4、接收許可協議 點擊“我接受” 5、選擇安裝路徑 “瀏覽”選擇安裝路徑,點擊"安裝" 6、完成…

web安全攻防入門教程

Web安全攻防入門教程 Web安全攻防是指在Web應用程序的開發、部署和運行過程中&#xff0c;保護Web應用免受攻擊和惡意行為的技術與策略。這個領域不僅涉及防御措施的實現&#xff0c;還包括通過滲透測試、漏洞挖掘和模擬攻擊來識別潛在的安全問題。 本教程將帶你入門Web安全攻…

前端node環境安裝:nvm安裝詳細教程(安裝nvm、node、npm、cnpm、yarn及環境變量配置)

需求&#xff1a;在做前端開發的時候&#xff0c;有的時候 這個項目需要 node 14 那個項目需要 node 16&#xff0c;我們也不能卸載 安裝 。這豈不是很麻煩。這個時候 就需要 一個工具 來管理我們的 node 版本和 npm 版本。 下面就分享一個 nvm 工具 用來管理 node 版本。 這個…

Unity在運行狀態下,當物體Mesh網格發生變化時,如何讓MeshCollider碰撞體也隨之實時同步變化?

舊版源代碼地址&#xff1a;https://download.csdn.net/download/qq_41603955/90087225?spm1001.2014.3001.5501 舊版效果展示&#xff1a; 新版加上MeshCollider后的效果&#xff1a; 注意&#xff1a;在Unity中&#xff0c;當你動態地更改物體的Mesh時&#xff0c;通常期望…