顾名思义,迭代器模式就是顺序访问聚集中的对象,一般来说,集合中非常常见,如果对集合类比较熟悉的话,理解本模式会十分轻松。这句话包含两层意思:一是需要遍历的对象,即聚集对象,二是迭代器对象,用于对聚集对象进行遍历访问。我们看下关系图:
这个思路和我们常用的一模一样,MyCollection中定义了集合的一些操作,MyIterator中定义了一系列迭代操作,且持有Collection实例,我们来看看实现代码:
两个接口:
- public interface Collection {
- public Iterator iterator();
- /*取得集合元素*/
- public Object get(int i);
- /*取得集合大小*/
- public int size();
- }
- public interface Iterator {
- //前移
- public Object previous();
- //后移
- public Object next();
- public boolean hasNext();
- //取得第一个元素
- public Object first();
- }
两个实现:
- public class MyCollection implements Collection {
- public String string[] = {"A","B","C","D","E"};
- @Override
- public Iterator iterator() {
- return new MyIterator(this);
- }
- @Override
- public Object get(int i) {
- return string[i];
- }
- @Override
- public int size() {
- return string.length;
- }
- }
- public class MyIterator implements Iterator {
- private Collection collection;
- private int pos = -1;
- public MyIterator(Collection collection){
- this.collection = collection;
- }
- @Override
- public Object previous() {
- if(pos > 0){
- pos--;
- }
- return collection.get(pos);
- }
- @Override
- public Object next() {
- if(pos<collection.size()-1){
- pos++;
- }
- return collection.get(pos);
- }
- @Override
- public boolean hasNext() {
- if(pos<collection.size()-1){
- return true;
- }else{
- return false;
- }
- }
- @Override
- public Object first() {
- pos = 0;
- return collection.get(pos);
- }
- }
测试类:
- public class Test {
- public static void main(String[] args) {
- Collection collection = new MyCollection();
- Iterator it = collection.iterator();
- while(it.hasNext()){
- System.out.println(it.next());
- }
- }
- }
输出:A B C D E
此处我们貌似模拟了一个集合类的过程,感觉是不是很爽?其实JDK中各个类也都是这些基本的东西,加一些设计模式,再加一些优化放到一起的,只要我们把这些东西学会了,掌握好了,我们也可以写出自己的集合类,甚至框架!
==================================================================
下面看迭代子的另外一个例子:
package my; public class Test { public static void main(String[] args) { Stack s = new Stack(); s.push("Liucy"); s.push("Huxz"); s.push("George"); print(s.iterator()); LinkedList l = new LinkedList(); l.addFirst("Liucy"); l.addFirst("Huxz"); l.addFirst("George"); print(l.iterator()); } public static void print(Itr it) { while (it.hasNext()) { System.out.println(it.next()); } } } interface Itr { boolean hasNext(); Object next(); } class Stack { Object[] os = new Object[10]; int index = 0; private void expand() { Object[] os2 = new Object[os.length * 2]; System.arraycopy(os, 0, os2, 0, os.length); os = os2; } public void push(Object o) { if (index == os.length) expand(); os[index] = o; index++; } public Object pop() { index--; Object o = os[index]; os[index] = null; return o; } private class StackItr implements Itr { int cursor = 0; public boolean hasNext() { return cursor < index; } public Object next() { return os[cursor++]; } } public Itr iterator() { return new StackItr(); } } class LinkedList { private class Node { Object o; Node next; public Node(Object o) { this.o = o; } public void setNext(Node next) { this.next = next; } public Node getNext() { return this.next; } } Node head; public void addFirst(Object o) { Node n = new Node(o); n.setNext(head); head = n; } public Object removeFirst() { Node n = head; head = head.getNext(); return n.o; } class LinkedListItr implements Itr { Node currentNode = head; public boolean hasNext() { return this.currentNode != null; } public Object next() { Node n = currentNode; currentNode = currentNode.getNext(); return n.o; } } public Itr iterator() { return new LinkedListItr(); } }
===============================================================
2、
抽象聚集角色类,这个角色规定出所有的具体聚集必须实现的接口。迭代子模式要求聚集对象必须有一个工厂方法,也就是createIterator()方法,以向外界提供迭代子对象的实例。
public abstract class Aggregate { /** * 工厂方法,创建相应迭代子对象的接口 */ public abstract Iterator createIterator(); }
具体聚集角色类,实现了抽象聚集角色类所要求的接口,也就是createIterator()方法。此外,还有方法getElement()向外界提供聚集元素,而方法size()向外界提供聚集的大小等。
public class ConcreteAggregate extends Aggregate { private Object[] objArray = null; /** * 构造方法,传入聚合对象的具体内容 */ public ConcreteAggregate(Object[] objArray){ this.objArray = objArray; } @Override public Iterator createIterator() { return new ConcreteIterator(this); } /** * 取值方法:向外界提供聚集元素 */ public Object getElement(int index){ if(index < objArray.length){ return objArray[index]; }else{ return null; } } /** * 取值方法:向外界提供聚集的大小 */ public int size(){ return objArray.length; } }
抽象迭代子角色类
public interface Iterator { /** * 迭代方法:移动到第一个元素 */ public void first(); /** * 迭代方法:移动到下一个元素 */ public void next(); /** * 迭代方法:是否为最后一个元素 */ public boolean isDone(); /** * 迭代方法:返还当前元素 */ public Object currentItem(); }
具体迭代子角色类
public class ConcreteIterator implements Iterator { //持有被迭代的具体的聚合对象 private ConcreteAggregate agg; //内部索引,记录当前迭代到的索引位置 private int index = 0; //记录当前聚集对象的大小 private int size = 0; public ConcreteIterator(ConcreteAggregate agg){ this.agg = agg; this.size = agg.size(); index = 0; } /** * 迭代方法:返还当前元素 */ @Override public Object currentItem() { return agg.getElement(index); } /** * 迭代方法:移动到第一个元素 */ @Override public void first() { index = 0; } /** * 迭代方法:是否为最后一个元素 */ @Override public boolean isDone() { return (index >= size); } /** * 迭代方法:移动到下一个元素 */ @Override public void next() { if(index < size) { index ++; } } }
客户端类
public class Client { public void operation(){ Object[] objArray = {"One","Two","Three","Four","Five","Six"}; //创建聚合对象 Aggregate agg = new ConcreteAggregate(objArray); //循环输出聚合对象中的值 Iterator it = agg.createIterator(); while(!it.isDone()){ System.out.println(it.currentItem()); it.next(); } } public static void main(String[] args) { Client client = new Client(); client.operation(); }