迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。
迭代器模式是针对集合对象而生的,对于集合对象而言,肯定会涉及到对集合的添加和删除操作,同时也肯定支持遍历集合元素的操作,我们此时可以把遍历操作放在集合对象中,但这样的话,集合对象既承担太多的责任了,面向对象设计原则中有一条就是单一职责原则,所有我们要尽可能地分离这些职责,用不同的类取承担不同的责任,迭代器模式就是用迭代器类来承担遍历集合的职责。
- 意图:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
- 主要解决:不同的方式来遍历整个整合对象。
- 何时使用:遍历一个聚合对象。
- 如何解决:把在元素之间游走的责任交给迭代器,而不是聚合对象。
- 关键代码:定义接口:hasNext, next。
1.3 Java代码实现
将书(Book)放到书架(BookShelf)中,并将书名按顺序显示。
Aggregate 接口
所要便利的集合的接口。实现了该接口的类将成为一个可以保存多个元素的集合,类似数组。
public interface Aggregate{
public abstract Iterator iterator();
}
Aggregate接口中声明的方法为iterator,作用为生成一个用于遍历的迭代器。
Iterator 接口
作用为遍历集合中元素,相当于循环语句中的循环变量(for(int i =0 ;i<arr.lenth;i++),具体实现一个顺序遍历的迭代器。
public interface Iterator{
public abstract boolean hasNext();
public abstract Object next();
}
hasNext() 方法判断是否存在下一个,next()方法获取下一个元素。
特殊说明下,next方法在获取元素的同时,要将计数器向下一个元素的计数加一。获取的是当前元素,并指向下一个元素。
Book类
普通类,书名field 获取书名的getName()方法。构造函数初始化书名。
public class Book{
private String name ;
public Book(String name){
this.name=name;
}
public String getName(){
return name;
}
}
BookShelf 类
书架类,作为存放书的集合类,实现Aggregate接口。实现了Aggregate接口的iterator方法。
public class BookShelf implements Aggregate {
private List<Book> books;
public BookShelf() {
this.books = new ArrayList<Book>();
}
public Book getBookAt(int index) {
return books.get(index);
}
public void appendBook(Book book) {
books.add(book);
}
public int getLength() {
return books.size();
}
// 返回iterator对象
public Iterator iterator() {
return new BookShelfIterator(this);
}
}
主要点在iterator方法,方法返回了遍历书架时要用的BookShelfIterator类作为书架的迭代器。当外部要遍历书架时会调用该方法。
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;
}
}
作为一个迭代器,要实现Iterator接口。index为迭代器当前所指向的下标。
hasNext判断还有没有下一本。通过下标和总数比较判断。
next获取当前书,并指向下一个。
测试类:
public class Main {
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf();
bookShelf.appendBook(new Book("Around the World in 80 Days"));
bookShelf.appendBook(new Book("Bible"));
bookShelf.appendBook(new Book("Cinderella"));
bookShelf.appendBook(new Book("Daddy-Long-Legs"));
Iterator it = bookShelf.iterator();
while (it.hasNext()) {
Book book = (Book) it.next();
System.out.println(book.getName());
}
}
}
控制台:
----------------------------------
Around the World in 80 Days
Bible
Cinderella
Daddy-Long-Legs
----------------------------------
Iterator模式中各角色的作用:
Iterator(迭代器):该角色责任定义按顺序逐个遍历元素的接口。程序中,由Iterator接口扮演,定义了hasNext和next两个方法。
Concretelterator(具体的迭代器):角色负责实现Iterator角色所定义的接口.该角色包含了遍历集合所必须的信息。
Aggregate(集合):该角色负责定义创建Iterator角色的接口。这个接口是一个方法会创建出一个,按照顺序访问保存在我内部元素的人。
ConcreteAggregate(具体集合):该角色负责实现Aggregate角色所定义的接口。他会创建出具体的Iterator角色,也就是ConcreteIterator,也就是实例中的BookShelf。