迭代器模式
迭代器模式(Iterator Pattern)是一种行为设计模式, 让你能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。所有迭代器必须实现相同的接口。 这样一来, 只要有合适的迭代器, 客户端代码就能兼容任何类型的集合或遍历算法。 如果你需要采用特殊方式来遍历集合, 只需创建一个新的迭代器类即可, 无需对集合或客户端进行修改。
何时使用:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
关键代码:定义接口:hasNext, next。
优点: 1、开闭原则。 2、单一职责原则。
缺点:由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
代码实现
定义迭代器接口
public interface Iterator_<E> { //Element //Type //K //Value V Tank
boolean hasNext();
E next(); //Tank next() Iterator_<Tank> it = ... Tank t = it.next();
}
定义容器接口
public interface Collection_<E> {
void add(E o);
int size();
Iterator_ iterator();
}
链表形式的容器实现类,相比数组,这个容器不用考虑边界问题,可以动态扩展,内部实现迭代器逻辑
class LinkedList_<E> implements Collection_<E> {
Node head = null;
Node tail = null;
//目前容器中有多少个元素
private int size = 0;
public void add(Object o) {
Node n = new Node(o);
n.next = null;
if(head == null) {
head = n;
tail = n;
}
tail.next = n;
tail = n;
size++;
}
private class Node {
private Object o;
Node next;
public Node(Object o) {
this.o = o;
}
}
public int size() {
return size;
}
@Override
public Iterator_<E> iterator() {
return new ArrayListIterator();
}
private class ArrayListIterator<E> implements Iterator_<E> {
private Node iterator_node = head;
@Override
public boolean hasNext() {
if(iterator_node == null) return false;
return true;
}
@Override
public E next() {
E o = (E)iterator_node.o;
iterator_node=iterator_node.next;
return o;
}
}
}
数组形式的容器实现类,相比数组,这个容器不用考虑边界问题,可以动态扩展,内部实现迭代器逻辑。
class ArrayList_<E> implements Collection_<E> {
E[] objects = (E[])new Object[10];
//objects中下一个空的位置在哪儿,或者说,目前容器中有多少个元素
private int index = 0;
public void add(E o) {
if(index == objects.length) {
E[] newObjects = (E[])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_<E> iterator() {
return new ArrayListIterator();
}
private class ArrayListIterator<E> implements Iterator_<E> {
private int currentIndex = 0;
@Override
public boolean hasNext() {
if(currentIndex >= index) return false;
return true;
}
@Override
public E next() {
E o = (E)objects[currentIndex];
currentIndex ++;
return o;
}
}
}
实现类
在实现类中,只需要切换方法第一行中的new对象即可切换不同的容器方法。同时即使遍历方式不同实现类代码中也不需要变动。
public class Main {
public static void main(String[] args) {
Collection_<String> list = new LinkedList_<>();
for(int i=0; i<15; i++) {
list.add(new String("s" + i));
}
System.out.println(list.size());
//这个接口的调用方式:
Iterator_<String> it = list.iterator();
while(it.hasNext()) {
String o = it.next();
System.out.println(o);
}
}
}