1、迭代器模式
在刚开始学习编程的时候,一定会学习程序流程的三种结构:顺序,循环,选择。而在学习循环时,肯定会学习数组的 for 循环:
int[] num = {1,2,3,4,5,6,7,8,9};
for(int i = 0; i < num.length; i++){
System.out.println(num[i]);
}
以上 for 循环实现的是对数组 num 的遍历,而迭代器模式实际上提供的也是这样的一种遍历方式。
思考这样一种场景,我们在主程序中从前往后遍历一个数组,现在要将遍历方式改成从后往前,那么我们需要着手在主程序中修改代码:
int[] num = {1,2,3,4,5,6,7,8,9};
for(int i = num.length-1; i >= 0; i--){
System.out.println(num[i]);
}
亦或者将数组改为一个 List 集合,即改为遍历一个 List 集合:
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
是不是觉得这样太麻烦了,如果这些数组、集合能自己提供一个遍历函数给我们是不是就方便了许多。
譬如,要遍历的集合中有两个函数:
- hasNext 判断集合是否存在下一个元素;
- next 返回集合的下一个元素。
那么对于任何一种集合,都可用以下代码来进行集合遍历:
while(hasNext()){
System.out.println(next());
}
这就是迭代器模式,用于在数据集合中按照某种顺序遍历集合。为了让每一个数据集合都能提供遍历函数,可以定义如下接口:
public interface Aggregate {
Iterator iterator();
}
在 Aggregate 接口中定义了 iterator 函数,该函数返回一个用于遍历集合的迭代器,只要类实现了 Aggregate 接口,那么该类就提供迭代器,而迭代器定义如下,两个函数的作用如上所述:
public interface Iterator {
Boolean hasNext();
Object next();
}
2、实例解析
假设现在有一个书架,书架上面都是书籍,现在要对书架进行遍历。
- 对书籍类进行定义:
public class Book {
private String name;
public Book(String name){
this.name = name;
}
public String getName(){
return name;
}
}
- 让书架类实现 Aggregate 接口,以便提供迭代器
public class BookShelf implements Aggregate {
private List<Book> books;
private Integer index;
public BookShelf(int maxSize){
books = new ArrayList<>(maxSize);
index = 0;
}
@Override
public Iterator iterator() {
return new BookShelfIterator(this);
}
}
- 使书架迭代器实现 Iterator 接口,并在其中对 hasNext 以及 next 函数重写
public class BookShelfIterator implements Iterator {
private BookShelf bookShelf;
public BookShelfIterator(BookShelf bookShelf){
this.bookShelf = bookShelf;
}
@Override
public Boolean hasNext() {
return bookShelf.getIndex()<bookShelf.getBooks().size();
}
@Override
public Object next() {
Book book = bookShelf.getBooks().get(bookShelf.getIndex());
bookShelf.setIndex(bookShelf.getIndex()+1);
return book;
}
}
- 在 main 函数中对书架迭代进行测试
public class Main {
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf(4);
bookShelf.getBooks().add(new Book("a"));
bookShelf.getBooks().add(new Book("b"));
bookShelf.getBooks().add(new Book("c"));
bookShelf.getBooks().add(new Book("d"));
Iterator iterator = bookShelf.iterator();
while(iterator.hasNext()){
System.out.println(((Book)iterator.next()).getName());
}
}
}
在本实例中,如果将书架类中的 List<Book> 替换为其他集合,也只需修改迭代器中的 hasNext 和 next 函数,无需修改主程序中的代码。