Iterator,自然而然想到的是用于集合遍历的迭代器Iterator,没错Iterator模式就是指这个意思。
先来看一段代码:
int[] array = new int[10];for(int i = 0; i
上面是编程里面很常见的遍历数组的用法,假如我不直接操作array对象,然后将用于表示下标的 i 抽象化,通用化,将遍历的动作交给迭代器,那么这种模式就叫做Iterator模式。
举一个示例,有一个书架和一些书,每一本书作为一个个体(实例),书架可以理解为这些个体的集合。
介绍一下上面的各个“东西”:
Aggregate:一个集合接口,凡是实现这个接口的iterator方法,就具有集合的功能;
Iterator:一个具有遍历功能的迭代器接口,里面定义了迭代需要的方法;
BookShelf:集合的具体实现类;
BookShelfIterator:迭代器接口的具体实现类;
Book:个体类。
1、Aggregate接口定义:
public interface Aggregate{ public abstract Iterator iterator();}
2、Iterator接口:
public interface Interator{ public abstract boolean hasNext(); public abstract Object next();}
里面很简单,只定义了两个方法:hasNext和next。使用过集合迭代器的小伙伴都知道,hasNext用于判断是否存在元素,next获取当前元素的同时,将下标指向下一个元素。
3、BookShelf类定义
public class BookShelf implement Aggregate{ private Book[] books; private int last = 0; public BookShelf(int maxsize){ books = new Book[maxsize]; } public Book getBookAt(int index){ return books[index]; } public void appendBook(Book book){ books[last] = book; last++; } public int getLength(){ return last; } public Iterator iterator(){ return new BookShelfIterator(this); } }
构造方法根据参数创建指定大小的Book数组,appendBook用于给数组添加元素,getLength获取当前数组长度(正确来说是当前数组最后一个元素的下标+1),另外,还实现了Aggregate的抽象方法iterator(),上面也提及到,只要一个类实现了Aggregate接口,就具有集合的功能,即遍历功能,在这里,只是用于创建迭代器的实现类BookShelfIterator,遍历的具体功能交给BookShelfIterator实现类去实现。
4、BookShelfIterator类定义
public class BookShelfIterator implements Iterator{ private BookShelf bookShelf; private int index; public BookShelfIterator(BookShelf bookShelf){ this.bookShelf = bookShelf; this.index = 0; } public boolean hasNext(){ if(index < bookShelf.getLength()){ return true; } else { return false; } } public Object next(){ Book book = bookShelf.getBookAt(index); index++; return book; }}
很简单,构造方法里将BookShelf对象作为参数,当前属性指向BookShelf对象,用于操作获取BookShelf元素,以及BookShelf长度。hashNext的实现逻辑只是对BookShelf对象的长度做一个判断,如果当前下标小于BookShelf长度,那么就返回true,否则,返回false。next方法,除了返回指定下标元素之外,还将下标向后推移了一位,即next实现了两个功能。
5、Book类定义
public class Book{ private String name; public Book(String name){ this.name = name; } public String getName(){ return name; }}
至于测试方法,这里不写出来了。
我们就会发现,开头那段for代码里面的i++,就相当于next()方法里面的index++操作,都是用于指向下一位元素。上面代码的实现效果相当于ArrayList,不过BookShelf这个集合类这样子写,是会出问题的,ArrayList对象是可以“无限”添加元素,但是BookShelf最大只能添加maxsize个元素,所以可以进行改进。
改进后的BookShelf类:
public class BookShelf implement Aggregate{ private List Books; public BookShelf(int initialsize){ books = new ArrayList(initialsize); } public Book getBookAt(int index){ return (Book)books.get(index); } public void appendBook(Book book){ books.add(book); } public int getLength(){ return books.size(); } public Iterator iterator(){ return new BookShelfIterator(this); } }
至于为什么要使用Iterator呢?一个重要原因是,可以将遍历与实现分离开来。对BookShelf对象进行遍历的时候,会用到下面代码:
Iterator it = bookShelf.iterator();while(it.hasNext()){ Book book = (Book)it.next(); System.out.println(book.getName());}
遍历的过程,根本没有使用过BookShelf类的方法,完全不需要理会BookShelf的实现,也不知道BookShelf怎么实现,但是Iterator知道,所以只需要调用Iterator的方法就可以实现遍历BookShelf集合的效果。这样设计的好处就是,可以根据的实际业务需求来增加遍历的功能,使得原有的代码不改动或少改,达到一个低耦合的效果。