三分钟掌握“迭代器模式”——轻松搞定设计模式

迭代器模式的官方定义:

迭代器模式提供了一种方法,它能够顺序访问一个集合对象中的各个元素,并且又不暴露该对象的内部结构。

不使用迭代器模式实现容器的迭代:

当我们拿到一个含有集合的对象时,如果我们想要遍历对象中的集合,就必须要知道对象的内部结构,然后使用for循环遍历对象中的集合。而且当我们需要换一种遍历方式的时候(如:顺序遍历换成逆序遍历),需要修改客户端的代码,这就违背了“封闭-开放原则”。但如果使用了迭代器模式之后,需要换迭代方式时,只需要增加一个迭代器类,然后稍微修改一下集合对象中的代码,而客户端代码一句也不要动;也就是说,使用了迭代器模式之后,当需要更换迭代方式的时候,我们再增加一个类,而不是修改代码,从而体现了“开放-封闭原则”。

PS:开放-封闭原则:开放扩展,封闭更改。代码一旦写完就不要再去修改,若要增加功能,通过拓展继承体系(也就是增加类)来实现。

迭代器模式类图:

1.首先需要有一个存放许多数据的容器,我们把它称为Collection;其次需要再创建一个类,专门用来遍历容器中的数据,我们把这个类称为Iterator;而且Iterator中包含了遍历容器的一些基本函数。

2.由于容器的内部构造都不尽相同,但他们都需要使用迭代器遍历,因此我们抽象出容器们的公共接口,这个接口中只有一个获取迭代器的函数:iterator();

3.由于每个容器内部构造都不一样,所以迭代这些容器的迭代器的具体实现也不一样,所以我们需要为每一个容易简历一个专门的迭代器类,针对每种容器的内部结构,实现了Iterator接口中的函数。

4.由于具体的迭代器需要知道它所服务的容器的内部结构,所以要在构造迭代器的时候将容器的对象传给迭代器,迭代器拿到具体的容器对象之后,就可以根据这个容器的特性重写next、hasNext、first这些函数了。

5.最后,当迭代器和容器都写好之后,就可以交付给客户使用了。

客户通过容器的iterator函数获得该容器对应的迭代器对象,然后使用该迭代器对象的一些函数就可以遍历容器元素了。

PS:客户通过调用容器对象的iterator函数创建该容器对应的Iterator对象时,该容器的对象将会传递给Iterator对象:

private Iterator it; 

@Override

public Iterator iterator() {

this.it = new AIterator(this);

return this.it;

}

当AIterator对象获取到它所服务的容器对象之后,才能针对该容器的结构重写next、hasNext、first这些函数。

迭代器模式的好处:

1.如果要更换一个具体容器的迭代方式的时候,客户端不需要做任何改动,还是这么写:

Iterator it = collection.iterator();

while(it.hasNext()){

   System.out.println(it.next());

}

我们只需要:

a)再创建一个迭代器类,重写里面的next、hasNext、first这些函数;

b)然后让容器类的iterator函数中创建Iterator对象时,将“旧的Iterator”换成“新的Iterator”

public Iterator iterator(){

this.it = new 新的Iterator();

}

因此,一个容器的迭代方式换了之后,不影响客户端的代码,降低了客户端与Iterator类和Collection类的耦合。

2.迭代器模式将集合对象的遍历行为单独封装在一个类中,这样既不暴露集合的内部结构,又可以使外部代码透明地访问集合内部的数据。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏别先生

Scala学习教程笔记三之函数式编程、集合操作、模式匹配、类型参数、隐式转换、Actor、

1:Scala和Java的对比: 1.1:Scala中的函数是Java中完全没有的概念。因为Java是完全面向对象的编程语言,没有任何面向过程编程语言的特性,因...

3085
来自专栏大闲人柴毛毛

深入Java虚拟机——JVM内存详解

在C++中,程序员拥有每一个对象的所有权,但与此同时还肩负着释放对象内存空间的责任;而Java由于有了虚拟机的帮助,程序员拥有对象的所有权的同时不再需要释放对象...

35112
来自专栏Java编程

《Effective Java》——读后总结

这本书在Java开发的行业里,颇有名气。今天总算是粗略的看完了...后面线程部分和序列化部分由于心浮气躁看的不仔细。这个月还剩下一周,慢慢总结消化。

4051
来自专栏一个会写诗的程序员的博客

Java8 Lambda表达式.md什么是λ表达式λ表达式的类型λ表达式的使用其它相关概念

为了支持函数式编程,Java 8引入了Lambda表达式. 在Java 8中采用的是内部类来实现Lambda表达式.具体实现代码,可以通过debug看, 同时...

643
来自专栏大闲人柴毛毛

深入JVM——OOM异常解析

JVM对象访问解析 对象访问过程的内存情况 public void function(){ Object obj = new Object(); } f...

33611
来自专栏java达人

最有价值的50道java面试题(二)

来自骆昊的技术专栏 26、抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchron...

19710
来自专栏Spark学习技巧

Scala语法基础之隐式转换

一,简介 从类型S到类型T的隐式转换由具有函数类型S => T的隐式值定义,或者通过可转换为该类型的值的隐式方法来定义。隐含转换适用于两种情况: 1),如果表达...

2059
来自专栏架构之路

JAVA基础知识点:内存、比较和Final

1.java是如何管理内存的 java的内存管理就是对象的分配和释放问题。(其中包括两部分) 分配:内存的分配是由程序完成的,程序员需要通过关键字new为每个对...

3594
来自专栏Java架构师进阶

BATJ架构师常见面试题汇总之一 让你瞬间升华起来

优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素...

422
来自专栏大闲人柴毛毛

深入Java虚拟机——JVM内存详解

在C++中,程序员拥有每一个对象的所有权,但与此同时还肩负着释放对象内存空间的责任;而Java由于有了虚拟机的帮助,程序员拥有对象的所有权的同时不再需要释放对象...

33513

扫描关注云+社区