迭代器模式(别名:游标)
提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
Iterator Pattern(Another Name: Cursor)
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
迭代器模式的结构中包括四种角色。
- 集合(Aggregate):一个接口,规定了具体集合需实现的操作。
- 具体集合(ConcreteAggregate):具体集合是实现集合接口的类的实例,具体集合按着一定结构存储对象。具体集合应当有一个方法,该方法返回一个针对该集合的具体迭代器。
- 迭代器(Iterator):一个接口,规定了遍历具体集合的方法,比如next()方法。
- 具体迭代器(ConcreteIterator):实现迭代器接口的类的实例。具体迭代器在实现迭代器接口所规定的遍历集合的方法时,比如next()方法,要保证next()方法的首次调用将按着集合的数据结构找到该集合中的一个对象,而且每当找到集合中的一个对象,立刻根据该集合的存储结构得到待遍历的后继对象的引用,并保证一次调用next()方法可以遍历集合。
迭代器模式的优点
- 用户使用迭代器访问集合中的对象,而不需要知道这些对象在集合中是如何表示及存储的。
- 用户可以同时使用多个迭代器遍历一个集合。
适合使用迭代器模式的情景
- 让用户访问一个集合的对象,但不想暴露对象在集合中的存储结构。
- 希望对遍历不同的集合提供一个统一的接口。
类图
ArrayList.java
package iterator;
import 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;
}
@Override
public Iterator iterator() {
return new ArrayListIterator();
}
private class ArrayListIterator implements Iterator {
private int currentIndex = 0;
@Override
public Object next() {
Object o = objects[currentIndex];
currentIndex++;
return o;
}
@Override
public boolean hasNext() {
if (currentIndex >= index)
return false;
else
return true;
}
}
}
Cat.java
package iterator;
public class Cat {
private int id;
public Cat(int id) {
this.id = id;
}
@Override
public String toString() {
return "Cat : " + id;
}
}
Collection.java
package iterator;
import iterator.Iterator;;
public interface Collection {
void add(Object o);
int size();
Iterator iterator();
}
Iterator.java
package iterator;
public interface Iterator {
Object next();
boolean hasNext();
}
LinkList.java
package iterator;
import iterator.Collection;
public class LinkList 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;
} else {
tail.setNext(n);
tail = n;
}
size++;
}
public int size() {
return size;
}
public Iterator iterator() {
return new LinkListIterator();
}
private class LinkListIterator implements Iterator {
private Node currentNode = head;
private Node preNode = head;
@Override
public Object next() {
Object o = currentNode.getData();
currentNode = preNode.getNext();
preNode = currentNode;
return o;
}
@Override
public boolean hasNext() {
if (currentNode != null)
return true;
else
return false;
}
}
}
Node.java
package iterator;
public class Node {
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
private Object data;
private Node next;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
Test.java
package iterator;
import iterator.ArrayList;
import iterator.LinkList;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
//ArrayList al = new ArrayList();
//LinkList al = new LinkList();
Collection c = new LinkList();
for (int i = 0; i < 15; i++) {
c.add(new Cat(i));
}
System.out.println(c.size());
Iterator it = c.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}