文档章节

折腾Java设计模式之迭代器模式

大萌小路
 大萌小路
发布于 03/08 08:59
字数 1250
阅读 20
收藏 0

迭代器模式

Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

提供一种不公示其底层细节(结构)的情况下能顺序访问聚合对象元素的方法。

其实在java体系中,jdk已经引入了迭代器接口以及对于的容器接口等。就拿迭代器中的角色,在java中找出其对应的类。

具体角色

(1)迭代器角色(Iterator):定义遍历元素所需要的方法,一般来说会有这么三个方法:取得下一个元素的方法next(),判断是否遍历结束的方法hasNext()),移出当前对象的方法remove(),

(2)具体迭代器角色(Concrete Iterator):实现迭代器接口中定义的方法,完成集合的迭代。

(3)容器角色(Aggregate): 一般是一个接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等

(4)具体容器角色(ConcreteAggregate):就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。

单独举出ArrayList的角色,

迭代器角色对应java中的java.lang.Iterator,这个迭代器是java容器公用的。

容器角色对应java.lang.Iterable,其还有Iterator<T> iterator()方法获取迭代器。

具体迭代器角色对应java.lang.ArrayList.Itr,实现了对应的hasNext、next、remove方法。

具体容器角色那就是java.lang.ArrayList了,实现iterator方法返回Itr具体迭代器,用游标形式实现。

再看看UML类

img

项目实例

源码在Github

项目中很简单的实现了一个容器和迭代器。大致参考了ArrayList实现,但是是简洁版本,去除很多无关以及性能上的东西,只保留最基本的迭代器元素。

@Slf4j
public class Application {

    public static void main(String[] args) {
        Aggregate<Integer> aggregate = new ConcreteAggregate<>();
        aggregate.add(1);
        aggregate.add(2);
        aggregate.add(3);
        aggregate.add(4);

        Iterator<Integer> iterator = aggregate.iterator();
        while (iterator.hasNext()) {
            log.info("循环数据{}", iterator.next());
        }
    }
}

执行结果如下

image-20190102175121620

简单的迭代器定义

public interface Iterator<E> {

    boolean hasNext();

    E next();

}

简单容器定义

public interface Aggregate<T> {

    Iterator<T> iterator();

    void add(T t);

}

具体容器和具体的迭代器定义

public class ConcreteAggregate<E> implements Aggregate<E> {

    private Object[] elements;

    private int size = 0;

    public ConcreteAggregate() {
        elements = new Object[16];
    }

    public int getSize() {
        return size;
    }

    public void add(E e) {
        elements[size++] = e;
    }

    @Override
    public Iterator<E> iterator() {
        return new ConcreteIterator<E>();
    }

    private class ConcreteIterator<E> implements Iterator<E> {

        int cursor;

        @Override
        public boolean hasNext() {
            return cursor != size;
        }

        @Override
        public E next() {
            if (cursor >= size) {
                return null;
            }
            return (E) elements[cursor++];
        }

    }
}

具体容器中用数组来作为容器来存储元素,而且最简单的容器,固定了大小,并没有实现扩容的算法等等,只是一个简单的样例,但是大部分上,都是直接使用java带有的迭代器。

优点

  • 简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。
  • 可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。
  • 封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心。

缺点

由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,大家可能都有感觉,像ArrayList,我们宁可愿意使用for循环和get方法来遍历集合。

总结

迭代器模式是与集合共生共死的,一般来说,我们只要实现一个集合,就需要同时提供这个集合的迭代器,就像java中的Collection,List、Set、Map等,这些集合都有自己的迭代器。假如我们要实现一个这样的新的容器,当然也需要引入迭代器模式,给我们的容器实现一个迭代器。

参考

wiki的迭代器模式

迭代器模式|菜鸟教程

Java设计模式系列之迭代器模式

欢迎关注

微

© 著作权归作者所有

大萌小路
粉丝 1
博文 21
码字总数 30936
作品 0
深圳
私信 提问
设计模式 2014-12-19

book: 阎宏《JAVA与模式》 架构设计栏目 http://blog.csdn.net/enterprise/column.html 概要: http://bbs.csdn.net/forums/Embeddeddriver 23种设计模式分别是: 1.单例模式 2.工厂方法模式...

jayronwang
2014/12/19
278
0
设计模式15——Template Method设计模式

Template Method模板方法设计模式定义一个操作中算法的骨架,将具体步骤的执行延迟到子类中实现。Java中的抽象类就是使用了模板方法设计模式。模板方法设计模式结构如下: 以文档处理为例,T...

小米米儿小
2014/01/24
207
0
23种设计模式(1):单例模式

定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。 类型:创建类模式 类图: 类图知识点: 1.类图分为三部分,依次是类名、属性、方法 2.以<<开头和以>>结尾的为注释...

LCZ777
2014/07/05
222
0
Java程序员从笨鸟到菜鸟之(三十三)大话设计模式(三)单例模式

本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188 单例模式属于对象创建型模式,其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点。对一些类来说...

长平狐
2012/11/12
156
0
java 23种设计模式 深入理解

以下是学习过程中查询的资料,别人总结的资料,比较容易理解(站在各位巨人的肩膀上,望博主勿究) 创建型 抽象工厂模式 http://www.cnblogs.com/java-my-life/archive/2012/03/28/2418836.html ...

wc_飞豆
2018/03/16
138
0

没有更多内容

加载失败,请刷新页面

加载更多

CSS盒子模型

一、什么叫框模型 页面元素皆为框(盒子) 定义了元素框处理元素内容,内边距,外边距以及边框的计算方式 二、外边距 围绕在元素边框外的空白距离(元素与元素之间的距离) 语法:margin,定...

wytao1995
今天
4
0
Replugin借助“UI进程”来快速释放Dex

public static boolean preload(PluginInfo pi) { if (pi == null) { return false; } // 借助“UI进程”来快速释放Dex(见PluginFastInstallProviderProxy的说明) return PluginFastInsta......

Gemini-Lin
今天
4
0
Hibernate 5 的模块/包(modules/artifacts)

Hibernate 的功能被拆分成一系列的模块/包(modules/artifacts),其目的是为了对依赖进行独立(模块化)。 模块名称 说明 hibernate-core 这个是 Hibernate 的主要(main (core))模块。定义...

honeymoose
今天
4
0
精华帖

第一章 jQuery简介 jQuery是一个JavaScript库 jQuery具备简洁的语法和跨平台的兼容性 简化了JavaScript的操作。 在页面中引入jQuery jQuery是一个JavaScript脚本库,不需要特别的安装,只需要...

流川偑
今天
7
0
语音对话英语翻译在线翻译成中文哪个方法好用

想要进行将中文翻译成英文,或者将英文翻译成中文的操作,其实有一个非常简单的工具就能够帮助完成将语音进行翻译转换的软件。 在应用市场或者百度手机助手等各大应用渠道里面就能够找到一款...

401恶户
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部