【设计模式大法】Iterator模式

Iterator模式 --一个一个遍历

 在Java中的for语句中 i++的作用是让 i 的值在每次循环后自增1,这样就可以访问数组中的下一个元素、下下一个元素、再下下一个元素,也就实现了从头至尾逐一遍历数组元素的功能。

将这里的循环变量 i的作用抽象化、通用化后形成的模式,在设计模式中称为 Iterator 模式

示例程序

  • Aggregate接口

    Aggregate接口是索要遍历的集合的接口。实现了该接口的类将称为一个可以保持多个元素的集合。

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

Aggregate接口中的iterator 方法将会生成一个用于遍历集合的迭代器。想要遍历集合中的元素的时候可以调用该方法来生成一个实现了Iterator接口的类的实例。

  • Iterator接口
public interface Iterator {
    public abstract boolean hasNext();
    public abstract Object next();
}

  hasNext()方法主要用于循环终止条件。

  next()方法用于返回集合中的一个元素,并且为了在下次调用next方法时正确地反回下一个元素,在该方法中还需将迭代器移动至下一个元素的处理。

  • Book类
public class Book {
    private String name;
    public Book(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}
  • BookShelf类
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;
    }
    
    public Itrator iterator() {
        return new BookShelfIterator(this);
    }
}

BookShelf类是用来表示书架的类,将该类作为Book的集合进行处理,实现了Aggregate接口。

  • 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;
    }
}

BookShelfIterator类是一个迭代器的实现,它持有一个将要遍历的集合BookShelf书架。

  • Main类
public class Main{
    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf(4);
        bookShelf.appendBook(new Book("倚天屠龙记"));
        bookShelf.appendBook(new Book("葵花宝典"));
        bookShelf.appendBook(new Book("九阳真经"));
        bookShelf.appendBook(new Book("神雕侠侣"));
        Iterator it = bookShelf.iterator();
        while (it.hasNext()){
            Book book = (Book) it.next();
            System.out.println(book.getName());
        }
    }
}

 

总结

  • 为何要使用Iterator

引入Iterator后可以将遍历与实现分离开来,在遍历时只需调用迭代器的方法,而不用关心具体集合实现类的方法。假设以后需要对集合类的实现方式进行修改,只要集合中的Iterator方法能正确的返回Iterator实例,即使不对迭代器的使用者进行修改,遍历代码都能正常工作。

设计模式的作用就是帮助我们编写可复用的类。“可复用”就是将类实现为“组件”,当一个组件发生改变时,不需要对其他的组件进行修改或只需很小的修改即可应对。

  • 多个Iterator

将遍历功能置于Aggregate角色之外,是Iterator模式的一个特征。根据这几个特征,可以针对一个具体的ConcreateAggregate角色编写多个ConcreteIterator角色。

  • 对JAVA集合进行遍历删除时务必要用迭代器。
 1 private class Itr implements Iterator<E> {
 2    /**
 3     * Index of element to be returned by subsequent call to next.
 4     */
 5    int cursor = 0;
 6    /**
 7     * Index of element returned by most recent call to next or
 8     * previous.  Reset to -1 if this element is deleted by a call
 9     * to remove.
10     */
11    int lastRet = -1;
12    /**
13     * The modCount value that the iterator believes that the backing
14     * List should have.  If this expectation is violated, the iterator
15     * has detected concurrent modification.
16     */
17    int expectedModCount = modCount;
18    public boolean hasNext() {
19            return cursor != size();
20    }
21    public E next() {
22            checkForComodification();
23        try {
24        E next = get(cursor);
25        lastRet = cursor++;
26        return next;
27        } catch (IndexOutOfBoundsException e) {
28        checkForComodification();
29        throw new NoSuchElementException();
30        }
31    }
32    public void remove() {
33        if (lastRet == -1)
34        throw new IllegalStateException();
35            checkForComodification();
36        try {
37        AbstractList.this.remove(lastRet);
38        if (lastRet < cursor)
39            cursor--;
40        lastRet = -1;
41        expectedModCount = modCount;
42        } catch (IndexOutOfBoundsException e) {
43        throw new ConcurrentModificationException();
44        }
45    }
46    final void checkForComodification() {
47        if (modCount != expectedModCount)
48        throw new ConcurrentModificationException();
49    }
50    }
ArrayList中的迭代器实现

 

posted @ 2017-05-07 14:14  代码简史  阅读(1353)  评论(0编辑  收藏  举报