迭代器模式的原理和实现
迭代器模式(Iterator Design Pattern),也叫作游标模式(Cursor Design Pattern)。
迭代器是用来遍历容器的,所以,一个完整的迭代器模式一般会涉及容器和容器迭代器两部 分内容。为了达到基于接口而非实现编程的目的,容器又包含容器接口、容器实现类,迭代 器又包含迭代器接口、迭代器实现类。
一个demo:
1 2 3 4 5 6
| public interface Iterator<E> { boolean hasNext(); void next(); E currentItem(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public class ArrayList<E> implements Iterator<E> { private int cursor; private ArrayList<E> arrayList; public ArrayIterator(ArrayList<E> arrayList) { this.cursor = 0; this.arrayList = arrayList; }
public Iterator iterator() { return new ArrayIterator(this); }
@Override public boolean hasNext() { return cursor != arrayList.size(); }
@Override public void next() { cursor++; }
@Override public E currentItem() { if (cursor >= arrayList.size()) { throw new NoSuchElementException(); } return arrayList.get(cursor); } }
public class Demo { public static void main(String[] args) { ArrayList<String> names = new ArrayList<>(); names.add("xzg"); names.add("wang"); names.add("zheng"); Iterator<String> iterator = names.iterator(); while (iterator.hasNext()) { System.out.println(iterator.currentItem()); iterator.next(); } } }
|

迭代器的优点
首先是Java中遍历的三种方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| List<String> names = new ArrayList<>(); names.add("xzg"); names.add("wang"); names.add("zheng");
for (int i = 0; i < names.size(); i++) { System.out.print(names.get(i) + ","); }
for (String name : names) { System.out.print(name + ",") }
Iterator<String> iterator = names.iterator(); while (iterator.hasNext()) { System.out.print(iterator.next() + ","); }
|
foreach 循环只是一个语法糖而已,底层是基于迭代器来实现的。
从代码上看,for循环要比 iterator简单,但是这是针对于数组这种数据结构来说的,如果是图或者树,用for循环则不那么容易。可以直接在迭代器中写好遍历,然后只注重与具体业务的开发,而不需要在业务层去书写这些遍历代码。
将游标指向的当前位置等信息,存储在迭代器类中,每个迭代器独享游标信息。这 样,我们就可以创建多个不同的迭代器,同时对同一个容器进行遍历而互不影响。
最后,容器和迭代器都提供了抽象的接口,方便我们在开发的时候,基于接口而非具体的实 现编程。当需要切换新的遍历算法的时候,比如,从前往后遍历链表切换成从后往前遍历链 表,客户端代码只需要将迭代器类从 LinkedIterator 切换为 ReversedLinkedIterator 即 可,其他代码都不需要修改。
参考
《设计模式之美》