折腾Java设计模式之迭代器模式
迭代器模式
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 iterator()方法获取迭代器。
具体迭代器角色对应java.lang.ArrayList.Itr,实现了对应的hasNext、next、remove方法。
具体容器角色那就是java.lang.ArrayList了,实现iterator方法返回Itr具体迭代器,用游标形式实现。
再看看UML类
项目实例
项目中很简单的实现了一个容器和迭代器。大致参考了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());
}
}
}
执行结果如下
简单的迭代器定义
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等,这些集合都有自己的迭代器。假如我们要实现一个这样的新的容器,当然也需要引入迭代器模式,给我们的容器实现一个迭代器。
参考
欢迎关注我的微信公众号
折腾Java设计模式之迭代器模式的更多相关文章
- 折腾Java设计模式之建造者模式
博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...
- 折腾Java设计模式之备忘录模式
原文地址:折腾Java设计模式之备忘录模式 备忘录模式 Without violating encapsulation, capture and externalize an object's int ...
- 折腾Java设计模式之状态模式
原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...
- 折腾Java设计模式之模板方法模式
博客原文地址:折腾Java设计模式之模板方法模式 模板方法模式 Define the skeleton of an algorithm in an operation, deferring some ...
- 折腾Java设计模式之访问者模式
博客原文地址:折腾Java设计模式之访问者模式 访问者模式 Represent an operation to be performed on the elements of an object st ...
- 折腾Java设计模式之命令模式
博客原文地址 折腾Java设计模式之命令模式 命令模式 wiki上的描述 Encapsulate a request as an object, thereby allowing for the pa ...
- 16.java设计模式之迭代器模式
基本需求: 展示一个学校的结构,比如一个学校下面有多个学院,学院下面有多个系,对其节点主要是遍历,与组合模式略有不同 传统方案: 学校<-学院<-系 依次继承 这种方式,在一个页面中展示出 ...
- 简单的了解下Java设计模式:迭代器模式(转载)
迭代器模式定义 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. Java 开发过程中遍历是常用的.如下边程序: for(int i =0 ; ...
- java设计模式之迭代器模式
一.迭代器模式简介 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 迭代器模式让我们能游走于聚合内的每一个元素,而又不暴露内部的表示.把游走的任务放在迭代器上,而不是 ...
随机推荐
- FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这个方案只能在java中运行,无法在Android项目中运行.所以此方案是:APP将表单数据发送给后台,后台通过freemarker ...
- 零基础入门学习javase,应该怎么学?这是我给你的一个建议
我们知道Java有三个方向,JavaSE,JavaME,JavaEE(老程序员可能会叫J2EE等,不过SUN已经改名了).JavaME主要是嵌入式与游戏开发.那我们先看JavaSE,因为只有学好了Ja ...
- javascript深入理解--作用域,作用域链,闭包的面试题解
一.概要 作用域和作用域链是js中非常重要的特性,关系到理解整个js体系,闭包是对作用域的延伸,其他语言也有闭包的特性. 那什么是作用域?作用域指的是一个变量和函数的作用范围. 1.js中函数内声明的 ...
- Netty源码—四、事件处理
前面经过channel初始化.注册,所需要的数据结构(epoll_event)基本上准备好了,serverSocket也处于监听状态,可以接收来自客户端的请求了.NioServerSocketChan ...
- 一目了然呀的VS2017 Live Test
刚刚试用了一下VS2017中的单元测试,发现,这一次,覆盖测试会自动标记出来.不用像以前一样要他细检查了.这次会自动帮你全部标记出来. 新建单元测试,使用MS的单元测试方案(VSTS使用的时候方便.) ...
- Java经典面试题+答案(全)
这套面试题主要目的是帮助那些还没有java软件开发实际工作经验,而正在努力寻找java软件开发工作的朋友在笔试时更好地赢得笔试和面试. 1.一个".java"源文件中是否可以包括多 ...
- Android进阶之光-第1章-Android新特性-读书笔记
第 1 章 Android 新特性 1.1 Android 5.0 新特性 1.1.1 Android 5.0 主要新特性 1. 全新的 Material Design 新风格 Material De ...
- Servlet不再是烦恼
Servlet 一.什么是Servlet? Servlet是在服务器上运行的小程序,也就是一个Java类,但比较特殊,不需要new,自动就可以运行.也有创建.垃圾回收和销毁过程.Servlet是Jav ...
- 使用dom4j 解析xml文件
//使用dom4j 解析xml文件,升级版,dom4j是对dom的封装 //重点 package com.offcn.utils; import java.io.File; import java.i ...
- 震惊!计算机连0.3+0.6都算不对?浅谈IEEE754浮点数算数标准
>>> 0.3+0.6 0.8999999999999999 >>> 1-0.9 0.09999999999999998 >>> 0.1+0.1+ ...