设计模式之Iterator:简单模拟java中集合类的实现

时间:2022-07-29 20:47:25

    Iterator模式也叫迭代模式,是由GoF提出的23种设计模式的一种。Iterator模式指对容器中包含的内部对象的访问委让给外部类,使用Iterator(遍历)按顺序进行遍历访问的设计模式。

迭代器模式由以下角色组成:
    1. 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。
    2.具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。
    3.容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。
    4.具体容器角色(Concrete Container):具体容器角色实现创建具体迭代器角色的接口——这个具体迭代器角色与该容器的结构相关。

    这里模拟java中集合类的实现,具体的UML图如下所示。

                                    设计模式之Iterator:简单模拟java中集合类的实现

     在程序设计中,经常有这种情况,需要从大量得数据(对象)集合中一个个地取出数据加以处理。Iterator模式就是为了有效地处理按顺序进行遍历访问的一 种设计模式,简单地说,Iterator模式提供一种有效的方法,可以屏蔽聚集对象集合的容器类的实现细节,而能对容器内包含的对象元素按顺序进行有效的遍历访问。

    如上图所示,ArrayList和LinkedList(具体容器角色)都实现了接口Collection(容器角色),ArrayListIterator和LinkedListIterator(具体迭代器角色)都实现了接口Iterator(迭代器角色),ArrayList和LinkedList的iterator()方法可以获取相应的具体的Iterator对象,由iterator对象完成对集合中元素的遍历访问。这样做法的好处是:

    1.简化容器的接口,让容器只实现本身的基本功能,把迭代功能委让给外部类实现;但是在java Collection中为了提高可扩展性,容器还是提供了遍历的接口。

     2.支持以不同的方式遍历一个容器角色。根据实现方式的不同,效果上会有差别。
     3.对同一个容器对象,可以同时进行多个遍历。因为遍历状态是保存在每一个迭代器对象中的。

    具体参考代码如下:

package com.zj.dp.iterator;
public interface Collection {
void add(Object o);
int size();
Iterator iterator();
}
package com.zj.dp.iterator;import com.zj.dp.iterator.Collection;public class ArrayList implements Collection {Object[] objects = new Object[10];int index = 0;public void add(Object o) {if(index == objects.length) {Object[] newObjects = new Object[objects.length * 2];System.arraycopy(objects, 0, newObjects, 0, objects.length);objects = newObjects;}objects[index] = o;index ++;}public int size() {return index;}public Iterator iterator() {return new ArrayListIterator();}private class ArrayListIterator implements Iterator {private int currentIndex = 0;@Overridepublic boolean hasNext() {if(currentIndex >= index) return false;else return true;}@Overridepublic Object next() {Object o = objects[currentIndex];currentIndex ++;return o;}}}
package com.zj.dp.iterator;import com.zj.dp.iterator.Collection;public class LinkedList implements Collection {Node head = null;Node tail = null;int size = 0;public void add(Object o) {Node n = new Node(o, null);if(head == null) {head = n;tail = n;}tail.setNext(n);tail = n;size ++;}public int size() {return size;}@Overridepublic Iterator iterator() {return new LinkedListIterator();}private class LinkedListIterator implements Iterator {private Object currentNode = head;@Overridepublic boolean hasNext() {if(currentNode == tail) return false;else return true;}@Overridepublic Object next() {Object o = currentNode;currentNode=((Node)currentNode).getNext();return o;}}}
package com.zj.dp.iterator;public interface Iterator {Object next();boolean hasNext();}
package com.zj.dp.iterator;public class Node {public Node(Object data, Node next) {super();this.data = data;this.next = next;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public Object getNext() {return next;}public void setNext(Node next) {this.next = next;}private Object data;private Node next;}
package com.zj.dp.iterator;public class Cat {public Cat(int id) {super();this.id = id;}private int id;@Overridepublic String toString() {return "cat:" + id;}}
package com.zj.dp.iterator;import com.zj.dp.iterator.ArrayList;import com.zj.dp.iterator.LinkedList;public class Test {public static void main(String[] args) {Collection c1 = new ArrayList();Collection c2 = new LinkedList();for(int i=0; i<15; i++) {c1.add(new Cat(i));c2.add(new Cat(15-i));}System.out.println(c1.size());System.out.println(c2.size());Iterator it1 = c1.iterator();Iterator it2 = c2.iterator();System.out.println("ArrayList中的内容如下:");while(it1.hasNext()) {Object o = it1.next();System.out.print(o + " ");}System.out.println("\nLinkedList中的内容如下:");while(it2.hasNext()) {Node o = (Node)it2.next();System.out.print(o.getData() + " ");}}}