设计模式之Iterator模式

103 阅读1分钟

1、为什么要有Iterator?

  • 使用Iterator迭代器,可以方便我们遍历集合、数组等
  • 考虑以下情况,原本某一信息用数组存储,然而由于业务需求改为链表存储,那么需要在已有的业务代码中将所有的数组遍历改为链表遍历,这工作量无疑是巨大的并且容易出现失误。Iterator相当于在此之上封装了一层,只需要修改原类中的Iterator即可,起到了解耦的作用

2、Iterator实现示例

2.1、情景

在某图书管理系统中需要遍历所有书。

Book类

public class Book {
    String name;

    public Book(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

2.2、实现

对于图书管理系统(BookShelf类),我们需要实现其迭代器Iterator,首先需要有实现公共接口,规范了某类应该有迭代器

Aggregate类

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

对于BookShelf类,应该实现这个接口,以获取迭代器

public class BookShelf implements Aggregate{
    ArrayList<Book> books;

    public BookShelf() {
        this.books = new ArrayList<Book>();
    }

    @Override
    public Iterator iterator() {
        return new BookShelfIterator(this);
    }
}

而iterator方法内应该返回迭代器具体的实现,即 BookShelfIterator

public class BookShelfIterator implements Iterator {
    private BookShelf bookShelf;
    private Integer index;

    public BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
        this.index = 0;
    }
    
    @Override
    /**
     * 后续是否还有元素?是返回true,否则false
     */
    public boolean hasNext() {
        if (index < bookShelf.books.size()) {
            return true;
        }
        return false;
    }

    /**
     * 返回当前指针指向的元素,并且将指针后移
     * @return
     */
    @Override
    public Book next() {
        return bookShelf.books.get(index++);
    }
}

需要指出的是,这里实现的Iterator接口是java.util下定义的,是java指定的规范

3、应用

iterator的遍历如下

public class test {
    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf();
        bookShelf.books.add(new Book("海底两万里"));
        bookShelf.books.add(new Book("十万个为什么"));
        bookShelf.books.add(new Book("水浒传"));
        bookShelf.books.add(new Book("西游记"));
        Iterator iterator = bookShelf.iterator();
        while (iterator.hasNext()) {
            Book book = (Book)iterator.next();
            System.out.println(book.getName());
        }
    }
}

运行结果

image.png