Iterator模式----一个一个遍历

说起遍历,我立马就想到for循环,增强for循环,foreach循环这类的循环遍历,这个不错,既然有这么方便的遍历,为什么我们还要学习Iterator这样的遍历呢?

一个重要的理由是:引入Iterator后可以将遍历和实现分离开来

此话怎讲?什么意思呢?

来说明这样的一个场景:

刚开始写程序时,我们用的是Array,我们自定义的时候指定大小,然后用for循环进行遍历的如火如荼,突然有一天,要求变了,数组大小可变,并且要求使用ArrayList来定义这个集合,那么是不是所有的原来定义为Array的集合都需要改变,并改变其遍历方式啊?这样是不是很麻烦了!

那么问题来了,有没有一种方法或者模式,将遍历和实现分开呢?上面的遍历和实现是耦合在一块的,通过for循环来实现遍历,将for循环绑定到遍历上,如果for循环没法实现了(比如上面,Array被ArrayList代替了,那么for循环的长度由length变为size()了),那么遍历就泡汤了。呵呵,当然有这种方法了,那就是Iterator方式了。

怎么把这遍历和实现分离开呢?请看下文详细分解

这里有四个角色,分别是Iterator,CustomeIterator,Aggregate,CustomeAggregate;四个角色,这四个角色对应的不同的用处,具体如下:

Itertor:这个角色是个接口,用来定义顺序逐个遍历元素的API,包含hasNext和next两个方法。

CustomeIterator:这个是实现Iterator的具体类,用来处理实际上的工作,包含了遍历集合必须的信息(需要遍历的集合以及集合对应的下标)

Aggregate:定义创建Iterator的接口API,

CustomeIterator:实现Aggregate接口并制定Iterator实现的具体类CustomeIterator,并将自己指定为CustimeIterator需要的集合

其类图如下所示:

下面是测试案例

1,java util 的Iterator类,这个来自于java.util.Iterator,

2,自定义的BookShelfIterator类

package ModelItertor;

import java.util.Iterator;

public class BookShelfIterator implements Iterator {
    private int index;
    private BookShelf bookShelf;
    
    public BookShelfIterator(BookShelf bookShelf){
        this.bookShelf = bookShelf;
        this.index = 0;
    }
    
    public boolean hasNext() {
        return index<this.bookShelf.getLength();
    }

    public Object next() {
        Book book = this.bookShelf.getBookAt(index);
        index++;
        return book;
    }

}
View Code

3,Aggregate类

package ModelItertor;
import java.util.Iterator;

public interface Aggregate {
    public abstract Iterator iterator();
}
Aggregate

4,自定义的BookShelf类

package ModelItertor;

import java.util.Iterator;

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 i){
        if(i>=books.length){
            return books[books.length-1];
        }
        else{
            return books[i];
        }
    }
    
    public void appendBook(Book book){
        books[last] = book;
        last++;
    }
    
    public int getLength(){
        return this.last;
    }
    
    public Iterator iterator() {
        return new BookShelfIterator(this);
    }

}
View Code

5,测试的main类

package ModelItertor;
import java.util.Iterator;
public class Main {

    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf(4);
        bookShelf.appendBook(new Book("A"));
        bookShelf.appendBook(new Book("B"));
        bookShelf.appendBook(new Book("C"));
        bookShelf.appendBook(new Book("D"));
        Iterator it = bookShelf.iterator();
        while(it.hasNext()){
            Book book = (Book)it.next();
            System.out.println(book.getName());
        }
    }

}
Main

最终结果

A
B
C
D

那么,还是最上面的问题,为什么搞这么复杂呢?

现在有这样的一个需求,书的数量是可变的,也就是集合由以前的Array变为ArrayList,那么,我们只需要修改一下CustomeAggrator类的实现规则即可,对Iterator的类根本不用做任何改变,改变后的BookShelf类如下

package ModelItertor;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class BookShelfList implements Aggregate {

    private List bookList;
    
    public BookShelfList(int size){
        this.bookList = new ArrayList(size);
    }
    
    public Book GetBookAt(int i){
        return (Book) bookList.get(i);
    }
    
    public Iterator iterator() {
        return new BookShelfListIterator(this);
    }
    
    public int getLength(){
        return bookList.size();
    }
    
    public void appendBook(Book book){
        bookList.add(book);
    }
}
View Code

测试main方法如下

package ModelItertor;
import java.util.Iterator;
public class Main {

    public static void main(String[] args) {    
        BookShelfList booklist = new BookShelfList(2);
        booklist.appendBook(new Book("E"));
        booklist.appendBook(new Book("F"));
        booklist.appendBook(new Book("G"));
        booklist.appendBook(new Book("H"));
        
        Iterator it2 = booklist.iterator();
        while(it2.hasNext()){
            Book book = (Book)it2.next();
            System.out.println(book.getName());
        }
    }

}
View Code

 

posted @ 2015-03-20 08:41  凝荷  阅读(290)  评论(0编辑  收藏  举报