当前位置:首页 > 科技  > 软件

一文彻底搞明白迭代器模式

来源: 责编: 时间:2024-05-16 09:10:22 322观看
导读本篇讲解Java设计模式中的迭代器模式,分为定义、模式应用前案例、结构、模式应用后案例、适用场景、模式可能存在的困惑和本质探讨7个部分。定义迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不需暴露

本篇讲解Java设计模式中的迭代器模式,分为定义、模式应用前案例、结构、模式应用后案例、适用场景、模式可能存在的困惑和本质探讨7个部分。pRa28资讯网——每日最新资讯28at.com

定义

迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不需暴露该对象的内部表示。pRa28资讯网——每日最新资讯28at.com

在新的分类方式中,迭代器模式被划分至类之间的交互类别中,其简化的是调用方对一个或一组对象遍历行为的交互。pRa28资讯网——每日最新资讯28at.com

pRa28资讯网——每日最新资讯28at.com

模式应用前案例

在银行业务领域中,银行包含很多客户,而一个客户又可能包含多个账户。下面以这个案例进行说明。先来看一下未使用迭代器模式之前的代码实现。pRa28资讯网——每日最新资讯28at.com

public class Account {//账户类private final String accountNumber;private final double balance;public Account(String accountNumber, double balance) {this.accountNumber = accountNumber;this.balance = balance;    }// 省略其他属性和方法public String getAccountNumber(){return this.accountNumber;    }public double getBalance(){return this.balance;    }}public class Customer {//客户类private final String name;private final List<Account> accounts;public Customer(String name) {this.name = name;this.accounts = new ArrayList<>();    }public void addAccount(Account account) {this.accounts.add(account);    }// 遍历账户信息public void displayAccounts() {        System.out.println("Customer: " + this.name);//for (Account account : this.accounts) {//底层使用Iterator实现for(int i=0;i<this.accounts.size();i++) {            System.out.println("Account Number: " + this.accounts.get(i).getAccountNumber() + ", Balance: " + this.accounts.get(i).getBalance());        }    }}public class Bank {//银行集合类private final List<Customer> customers;public Bank(){this.customers = new ArrayList<>();    }// 添加顾客public void addCustomer(Customer customer){this.customers.add(customer);    }// 显示所有客户的帐号信息public void displayAllCustomersAndAccounts() {//for (Customer customer : this.customers) {//底层使用Iterator实现for(int i=0;i<this.customers.size();i++) {this.customers.get(i).displayAccounts();        }    }}public class Client {//调用方代码public static void main(String[] args) {        Bank bank= new Bank();        Customer customer1 = new Customer ("Sun");        customer1.addAccount(new Account( "1234" ,1000.0));        customer1.addAccount(new Account( "5678",500.0));        Customer customer2 = new Customer("Wang");        customer2.addAccount(new Account( "9012" ,200.0));        customer2.addAccount(new Account( "3456",40000));        bank.addCustomer(customer1);        bank.addCustomer(customer2);        bank.displayAllCustomersAndAccounts();    }}

对于迭代器模式,Java语言中的集合已经内置支持。在上述代码中,注释掉的增强的for循环方式(如for (Account account : this.accounts)),其底层也会转换成Iterator方式。pRa28资讯网——每日最新资讯28at.com

因此,主要是对比for(int i=0;i<size;i++)这种方式和Iterator迭代器方式之间的优劣。pRa28资讯网——每日最新资讯28at.com

结构

pRa28资讯网——每日最新资讯28at.com

迭代器模式的上述结构是一个通用的结构,其代码实现如下。pRa28资讯网——每日最新资讯28at.com

public interface Iterator<T> {T next();boolean hasNext();}public class ConcreteIterator<T> implements Iterator {private int currentIndex = 0;private T[] t;public ConcreteIterator(T[] t) {this.t = t;    }@Overridepublic Object next() {return t[currentIndex++];    }@Overridepublic boolean hasNext() {return currentIndex < t.length;    }}public interface Aggregate {Iterator createIterator();}public class ConcreteAggregate implements Aggregate {public String[] items;public ConcreteAggregate() {        items = new String[10];for(int i=0;i<items.length;i++) {            items[i] = "str"+i;        }    }@Overridepublic Iterator createIterator() {return new ConcreteIterator<String>(items);    }}public class Client {public static void main(String[] args) {        ConcreteAggregate aggregate = new ConcreteAggregate();        Iterator<String> iterator =  aggregate.createIterator();while (iterator.hasNext()) {            System.out.println(iterator.next());        }    }}

模式应用后案例

由于Java语言已经内置迭代器实现。上面的银行领域案例,如果应用迭代器模式,代码实现如下。pRa28资讯网——每日最新资讯28at.com

public class Account {//账户类private final String accountNumber;private final double balance;public Account(String accountNumber, double balance) {this.accountNumber = accountNumber;this.balance = balance;    }// 省略其他属性和方法public String getAccountNumber(){return this.accountNumber;    }public double getBalance(){return this.balance;    }}public class Customer {//客户类private final String name;private final List<Account> accounts;public Customer(String name) {this.name = name;this.accounts = new ArrayList<>();    }public void addAccount(Account account) {this.accounts.add(account);    }public Iterator<Account> iterator() {return this.accounts.iterator();    }public String getName() {return this.name;    }// 遍历账户信息public void displayAccounts() {//循环账户        Iterator<Account> acctIterator = this.iterator();while(acctIterator.hasNext()){            Account acount = acctIterator.next();            System.out.println("Acount Number:"+acount.getAccountNumber() + ", Balance: "+acount.getBalance());        }    }}public class Bank implements Iterable<Customer>{private final List<Customer> customers;public Bank() {this.customers =new ArrayList<>();    }// 添加顾客public void addCustomer(Customer customer){this.customers.add(customer);    }@Overridepublic Iterator<Customer> iterator(){return this.customers.iterator();    }// 显示所有客户的帐号信息public void displayAllCustomersAndAccounts() {        Iterator<Customer> customerIterator = this.iterator();//循环客户while(customerIterator.hasNext()) {            Customer customer = customerIterator.next();            System.out.println("Customer: " +customer.getName());            customer.displayAccounts();        }    }}public class Client {//调用方代码public static void main(String[] args) {        Bank bank = new Bank();        Customer customer1 = new Customer("Sun");        customer1.addAccount(new Account("1234", 1000.0));        customer1.addAccount(new Account("5678", 500.0));        Customer customer2= new Customer ("Wang");        customer2.addAccount(new Account( "9012" ,200.0));        customer2.addAccount(new Account( "3456",40000));        bank.addCustomer(customer1);        bank.addCustomer(customer2);        bank.displayAllCustomersAndAccounts();    }}

Java语言中提供了Iterable接口,然后重写里面的iterator方法。通过该方法就可以得到一个Iterator对象,然后可以利用这个Iterator对象就可以依次访问集合中的元素。pRa28资讯网——每日最新资讯28at.com

适用场景

迭代器模式适用于以下场景:pRa28资讯网——每日最新资讯28at.com

1、访问一个聚合对象的内容而无需暴露它的内部表示pRa28资讯网——每日最新资讯28at.com

2、支持对聚合对象的多种遍历方式,如树、图等pRa28资讯网——每日最新资讯28at.com

3、对遍历不同的聚合结构提供一个统一的接口pRa28资讯网——每日最新资讯28at.com

模式可能存在的困惑

困惑1:增强for循环(如for(obj:ObjList))与Iterator迭代器方式有何区别?pRa28资讯网——每日最新资讯28at.com

增强for循环方式相当于Java语言中的一种语法糖。在编译阶段,会转换成Iterator方式实现。pRa28资讯网——每日最新资讯28at.com

困惑2:普通for循环(如for(int i=0;i<size;i++))似乎也比较简洁,Iterator相比有什么优势?pRa28资讯网——每日最新资讯28at.com

针对数组、链表等简单的数据结构,两种循环方式其实体现不出优势。但是,对于树和图等复杂数据结构,普通for循环很难支持。pRa28资讯网——每日最新资讯28at.com

例如,对于树(Tree)这类数据结构,至少包括以下三种遍历方式:pRa28资讯网——每日最新资讯28at.com

1)前序遍历(Preorder Traversal):先访问根节点,然后递归地前序遍历左子树和右子树;pRa28资讯网——每日最新资讯28at.com

2)中序遍历(Inorder Traversal):先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树;pRa28资讯网——每日最新资讯28at.com

3)后序遍历(Postorder Traversal):先递归地后序遍历左子树和右子树,最后访问根节点。pRa28资讯网——每日最新资讯28at.com

对于图(Graph)这类数据结构,至少也要支持以下两种遍历方式pRa28资讯网——每日最新资讯28at.com

1)深度优先搜索(Depth-First Search, DFS):从起始顶点出发,在走过一条路径上所有未被标记过的顶点之前不回退;pRa28资讯网——每日最新资讯28at.com

2)广度优先搜索(Breadth-First Search, BFS):从起始顶点开始向外层扩散搜索,并且按照距离排序依次进行探索。pRa28资讯网——每日最新资讯28at.com

此外,由于迭代器是一个家族类,最上层是一个Iterable接口,后续也可以灵活扩展其他更高效的遍历方式。pRa28资讯网——每日最新资讯28at.com

本质

对于一个类来说,对于其属性或状态的遍历是类的一种行为。但是,这种行为不属于核心业务操作。pRa28资讯网——每日最新资讯28at.com

因此,迭代器模式的本质上是将这种遍历行为通用化,这样也可以为调用方提供统一的访问接口。pRa28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-88392-0.html一文彻底搞明白迭代器模式

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 揭秘 Java 跨系统文件路径组装的秘方!

下一篇: Kafka六大使用场景以及核心概念,你知道几个?

标签:
  • 热门焦点
  • 中兴AX5400Pro+上手体验:再升级 双2.5G网口+USB 3.0这次全都有

    2021年11月的时候,中兴先后发布了两款路由器产品,中兴AX5400和中兴AX5400 Pro,从产品命名上就不难看出这是隶属于同一系列的,但在外观设计上这两款产品可以说是完全没一点关系
  • Redmi Buds 4开箱简评:才199还有降噪 可以无脑入

    在上个月举办的Redmi Note11T Pro系列新机发布会上,除了两款手机新品之外,Redmi还带来了两款TWS真无线蓝牙耳机产品,Redmi Buds 4和Redmi Buds 4 Pro,此前我们在Redmi Note11T
  • 6月安卓手机好评榜:魅族20 Pro蝉联冠军

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年6月1日至6月30日,仅限国内市场。第一名:魅族20 Pro好评率:95%5月份的时候魅族20 Pro就是
  • 6月安卓手机性价比榜:Note 12 Turbo断层式碾压

    6月份有一个618,虽然这是京东周年庆的日子,但别的电商也都不约而同的跟进了,反正促销没坏处,厂商和用户都能满意。618期间一些产品也出现了历史低价,那么各个价位段的产品性价比
  • 线程通讯的三种方法!通俗易懂

    线程通信是指多个线程之间通过某种机制进行协调和交互,例如,线程等待和通知机制就是线程通讯的主要手段之一。 在 Java 中,线程等待和通知的实现手段有以下几种方式:Object 类下
  • 一文看懂为苹果Vision Pro开发应用程序

    译者 | 布加迪审校 | 重楼苹果的Vision Pro是一款混合现实(MR)头戴设备。Vision Pro结合了虚拟现实(VR)和增强现实(AR)的沉浸感。其高分辨率显示屏、先进的传感器和强大的处理能力
  • 零售大模型“干中学”,攀爬数字化珠峰

    文/侯煜编辑/cc来源/华尔街科技眼对于绝大多数登山爱好者而言,攀爬珠穆朗玛峰可谓终极目标。攀登珠峰的商业路线有两条,一是尼泊尔境内的南坡路线,一是中国境内的北坡路线。相
  • 冯提莫签约抖音公会 前“斗鱼一姐”消失在直播间

    来源:直播观察提起&ldquo;冯提莫&rdquo;这个名字,很多网友或许听过,但应该不记得她是哪位主播了。其实,作为曾经的&ldquo;斗鱼一姐&rdquo;,冯提莫在游戏直播的年代影响力不输于现
  • 苹果MacBook Pro 2021测试:仍不支持平滑滚动

    据10月30日9to5 Mac 消息报道,苹果新的 14 英寸和 16 英寸 MacBook Pro 2021 上市后获得了不错的评价,亮点包括行业领先的性能,令人印象深刻的电池续航,精美丰
Top