Java设计模式(二) 之 迭代器模式
2015-08-04 09:13
561 查看
源码均以JDK1.8作为参考
1.定义:
Iterator提供一种方法访问一个容器对象中各个元素,而又不需要暴露对象的内部细节。
2.解析:
通用类图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/15/847a265e9b7b051289be82fbe40cd6ab)
类图解析:
2.1.Iterator抽象迭代器
抽象迭代器负责定义通用的接口约定,基本都是基于JDK中Iterator接口的定义,源码如下:
基本的Iterator都会有hasNext()、next()两个方法定义的约束,remove()方法提供了在遍历时删除容器内部元素,在JDK1.8中加入了default方法forEachRemaining(Consumer action),使得在遍历时,可以指定一个action进行遍历。
2.2.Concrete Iterator具体迭代器
Concrete Iterator实现了Iterator接口,并实现了其内部的方法定义,完成具体的迭代,此时的Iterator可以用两种方式实现。
一种是ConcreteIterator持有具体容器集合的引用,迭代时遍历集合的元素,常规的Iterator都是按照此种方式实现的。
一种是ConcreteIterator作为容器集合的内部类使用,由于内部类的特殊性,可以随时获得外部类的具体实现,完成迭代操作,但是此种实现的Iterator具有依赖性,不可重复使用。
2.3.Aggregate抽象容器
Aggregate抽象容器在Iterator模式中是一个可有可无的存在,定义了容器的一些上层操作,目的是针对多个容器之间关联性的处理。
2.4.Concrete Aggregate具体容器
具体容器的实现,需要定义其内部结构等,例如ArrayList依赖数组完成元素的存取、HashMap依赖数组、链表完成元素的存取等。
3.具体应用:
上面介绍的是Iterator设计模式的通用方式,接下来根据其通用定义完成一个简单的示例,通过Iterator模式进行遍历。
3.1.Iterator抽象迭代器
此迭代器约定使用java.util.Iterator的定义。
3.2.Concrete Iterator具体迭代器
3.3.Aggregate抽象容器
3.4.Concrete Aggregate具体容器
示例中ConcreteAggregate具体容器内部使用Vector作为结构实现,可以使用如下代码:
4.forEachRemaining应用:
forEachRemaining是在JDK1.8中加入的接口的default方法,体现了JDK1.8中函数式编程思想
4.1.首先实现Consumer接口
4.2.使用Iterator实例进行迭代
注:以上是JDK1.8提供的函数式的处理方式,在低版本的JDK中是无法完成此类操作的。
5.注意:
1.尽管Iterator模式是一个很普遍的模式,但是一般的容器都已经提供了其具体实现,除非自己进行定义和实现容器,否则Iterator是没有必要的,另外需要注意的是在很多JDK容器的实现中,
对于实现了Iterator接口的容器类,有一些实现只是附加功能,像基于简单数组实现的容器类ArrayList、Vector等,其迭代器速度要比for循环的速度慢,而对于一些基于链表实现的容器类
LinkedList等,其迭代器的速度要比for循环的速度要快,所以在应用时,需要分情况进行具体考虑。
2.对于JDK1.7中新加入的for( : )快速迭代,正式基于Iterator的,只有实现了Iterator接口,并具有相应迭代器的集合容器,才可以使用其进行处理。
3.使用Iterator设计模式的最大理由是因为利用Iterator可以跟实现分开,单独进行递增。
4.过度依赖具体类反会提高类与类的耦合度,增加零部件复用的困难。为了降低耦合度,让类作为零件再利用,必须引进抽象类和接口的概念。
注:本人是参照《设计模式之禅》和《设计模式》两本书学习所得,其中加入了自己对于Iterator设计模式的理解,以及对于JDK中源码的理解。
1.定义:
Iterator提供一种方法访问一个容器对象中各个元素,而又不需要暴露对象的内部细节。
2.解析:
通用类图:
类图解析:
2.1.Iterator抽象迭代器
抽象迭代器负责定义通用的接口约定,基本都是基于JDK中Iterator接口的定义,源码如下:
public interface Iterator<E> { boolean hasNext(); E next(); default void remove() { throw new UnsupportedOperationException("remove"); } /* * @since 1.8 */ default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); } }
基本的Iterator都会有hasNext()、next()两个方法定义的约束,remove()方法提供了在遍历时删除容器内部元素,在JDK1.8中加入了default方法forEachRemaining(Consumer action),使得在遍历时,可以指定一个action进行遍历。
2.2.Concrete Iterator具体迭代器
Concrete Iterator实现了Iterator接口,并实现了其内部的方法定义,完成具体的迭代,此时的Iterator可以用两种方式实现。
一种是ConcreteIterator持有具体容器集合的引用,迭代时遍历集合的元素,常规的Iterator都是按照此种方式实现的。
一种是ConcreteIterator作为容器集合的内部类使用,由于内部类的特殊性,可以随时获得外部类的具体实现,完成迭代操作,但是此种实现的Iterator具有依赖性,不可重复使用。
2.3.Aggregate抽象容器
Aggregate抽象容器在Iterator模式中是一个可有可无的存在,定义了容器的一些上层操作,目的是针对多个容器之间关联性的处理。
2.4.Concrete Aggregate具体容器
具体容器的实现,需要定义其内部结构等,例如ArrayList依赖数组完成元素的存取、HashMap依赖数组、链表完成元素的存取等。
3.具体应用:
上面介绍的是Iterator设计模式的通用方式,接下来根据其通用定义完成一个简单的示例,通过Iterator模式进行遍历。
3.1.Iterator抽象迭代器
此迭代器约定使用java.util.Iterator的定义。
3.2.Concrete Iterator具体迭代器
public class ConcreteIterator implements Iterator { private Vector vector = new Vector(); // .. 定义当前游标 public int cursor = 0; @SuppressWarnings("unchecked") public ConcreteIterator(Vector _vector){ this.vector = _vector; } // .. 判断是否到达尾部 public boolean hasNext() { if(this.cursor == this.vector.size()){ return false; }else{ return true; } } // .. 返回下一个元素 public Object next() { Object result = null; if(this.hasNext()){ result = this.vector.get(this.cursor++); }else{ result = null; } return result; } // .. 删除当前元素 public boolean remove() { this.vector.remove(this.cursor); return true; } }
3.3.Aggregate抽象容器
public interface Aggregate { // .. 是容器必然有元素的增加 public void add(Object object); // .. 减少元素 public void remove(Object object); // .. 由迭代器来遍历所有的元素 public Iterator iterator(); }
3.4.Concrete Aggregate具体容器
public class ConcreteAggregate implements Aggregate { // .. 容纳对象的容器 private Vector vector = new Vector(); // .. 增加一个元素 public void add(Object object) { this.vector.add(object); } // .. 返回迭代器对象 public Iterator iterator() { return new ConcreteIterator(this.vector); } // .. 删除一个元素 public void remove(Object object) { this.remove(object); } }
示例中ConcreteAggregate具体容器内部使用Vector作为结构实现,可以使用如下代码:
public class Test{ public static void main(String[] args){ ConcreteAggregate ca = new ConcreteAggregate(); Iterator it = ca.iterator(); while(it.hashNext()){ it.next(); } } }
4.forEachRemaining应用:
forEachRemaining是在JDK1.8中加入的接口的default方法,体现了JDK1.8中函数式编程思想
4.1.首先实现Consumer接口
class Action implements Consumer{ @Override public void accept(Object o) { // .. 自己需要处理的事情 } }
4.2.使用Iterator实例进行迭代
ConcreteAggregate ca = new ConcreteAggregate(); Iterator it = ca.iterator(); it.forEachRemaining(new Action());
注:以上是JDK1.8提供的函数式的处理方式,在低版本的JDK中是无法完成此类操作的。
5.注意:
1.尽管Iterator模式是一个很普遍的模式,但是一般的容器都已经提供了其具体实现,除非自己进行定义和实现容器,否则Iterator是没有必要的,另外需要注意的是在很多JDK容器的实现中,
对于实现了Iterator接口的容器类,有一些实现只是附加功能,像基于简单数组实现的容器类ArrayList、Vector等,其迭代器速度要比for循环的速度慢,而对于一些基于链表实现的容器类
LinkedList等,其迭代器的速度要比for循环的速度要快,所以在应用时,需要分情况进行具体考虑。
2.对于JDK1.7中新加入的for( : )快速迭代,正式基于Iterator的,只有实现了Iterator接口,并具有相应迭代器的集合容器,才可以使用其进行处理。
3.使用Iterator设计模式的最大理由是因为利用Iterator可以跟实现分开,单独进行递增。
4.过度依赖具体类反会提高类与类的耦合度,增加零部件复用的困难。为了降低耦合度,让类作为零件再利用,必须引进抽象类和接口的概念。
注:本人是参照《设计模式之禅》和《设计模式》两本书学习所得,其中加入了自己对于Iterator设计模式的理解,以及对于JDK中源码的理解。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- 设计模式之行为型模式 - 调用行为的传递问题