读书笔记 仅供参考
Iterator迭代器的定义:迭代器(Iterator)模式,又叫做游标(Cursor)模式。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。
Iterator 模式
即为迭代器模式,用于在数据集合中按照顺序遍历集合。
Iterator(迭代器)
负责定义按顺序逐个遍历元素的方法,本身是一个接口,例如下面示例程序的 hasNext 和 next 方法。
ConcreteIterator(具体的迭代器)
实现 Iterator 定义的方法,例如程序中的 BookShelfIterator,在这个示例中应该存在需要遍历的集合(BookShelf)和指向集合的下标偏移量(index)
Aggregate(集合)
负责定义创建 Iterator 这个接口的方法,本身是一个接口,是集合类需要实现的接口。
ContcreteAggregate(具体的集合)
负责实现 Aggregate 定义的方法,本身也需要保存集合内的数据。
UML
示例程序
1.正如Aggregate和Iterator这两个接口是对应的一样,ConcreteAggregate和ConcreteIterator也是对应的。
2.将遍历与实现分离开来。
3.next方法的含义是 returnCurrentElementAndAdvanceNextPosition。
4.hasNext方法的含义是 是否能调用next。
代码
Aggregate,集合接口
public interface Aggregate {
//生成一个用于遍历的迭代器
Iterator itreator();
}
书本类,被遍历的对象
public class Book {
private String name;
public Book(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
ConcreteAggregate,实现 Aggregate 接口,并保存书本
public class BookShelf implements Aggregate {
private Book[] books;
private int last = 0;
//初始化书架最大容量
public BookShelf(int maxSize) {
this.books = new Book[maxSize];
}
//获取书本
public Book getBookAt(int index) {
return books[index];
}
//添加书本
public void appendBook(Book book) {
this.books[last] = book;
last++;
}
//获取现有书本数量
public int getLength() {
return last;
}
@Override
public Iterator itreator() {
return new BookShelfIterator(this);
}
}
Iterator 接口
public interface Iterator {
//判断是否存在下一个元素
boolean hasNext();
//返回下一个元素,并且移动迭代器
Object next();
}
ConcreteIterator,实现 Iterator 接口
public class BookShelfIterator implements Iterator {
private BookShelf bookShelf;
private int index;
//初始化书架和 index
public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
}
//根据书架中现有书本的数量判断
@Override
public boolean hasNext() {
if(index < bookShelf.getLength()) {
return true;
} else {
return false;
}
}
//返回下一本书,并且将 index 指向下一本书
@Override
public Object next() {
Book book = bookShelf.getBookAt(index);
index++;
return book;
}
}
主程序,试验迭代器
public class IteratorMain {
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf(4);
bookShelf.appendBook(new Book("book1"));
bookShelf.appendBook(new Book("book2"));
bookShelf.appendBook(new Book("book3"));
bookShelf.appendBook(new Book("book4"));
Iterator it = bookShelf.itreator();
while (it.hasNext()) {
Book book = (Book) it.next();
System.out.println(book.getName());
}
}
}
为何使用 Iteraor
引入 Iterator 可以将遍历和实现分离开来,遍历时只需要关心 hasNext 和 next 两个方法,不需要关心 BookShelf 是如何保存 Book 的,不管是数组、Vector 还是 List,遍历的程序都可以不用改变。
对应关系
Aggregate 和 Iterator 两个接口相对应,Aggregate 需要创建出 Iterator。
ConcreteIterator 和 ConcreteAggregate 这两个类相对应,就如 BookShelfIterator 和 BookShelf,BookShelfIterator 必须清楚如何处理 BookShelf,如果 BookShelf 发生了改变,就很有可能会修改 BookShelfIterator 。
易出错点
容易弄错下一个
next 方法应该是返回当前元素,并指向下一个元素
容易弄错最后一个
hasNext 判断是否能使用 next 方法。
相关设计模式
Visitor 模式
Iterator 模式从集合中取出元素进行遍历,但是不在接口声明中对元素进行何种处理。Visitor 模式是在一边遍历,一边处理。
Factor Method模式
在 iterator 方法中生成 Iterator 实例可能会使用 Factory Method 模式。