参考:1.《图解设计模式》

  1. https://blog.csdn.net/Lammonpeter/article/details/82142020
  2. JDK里的Iterator模式: https://www.cnblogs.com/tstd/p/5049338.html

Iterator模式适用于数据集合中按照顺序遍历集合

为什么在遍历的时候要额外引入迭代器这种复杂的模式呢?

引入迭代器设计模式的一个重要理由是:将实现和遍历进行了分离,也就是说遍历的过程完全不依赖与你所选择的集合是如何实现的 , 如果开发者换了其他的容器来承载数据,那么只需要修改集合的实现方式即可,完全不需要去修改遍历的过程代码,这就提高了代码的“可复用性”和“可靠性”。

JDK里的Iterator设计模式

List.pngArrayList.png
可以看到他们都实现了Iterable接口,Iterable接口的代码如下

  1. /**
  2. * Implementing this interface allows an object to be the target of
  3. * the "for-each loop" statement.
  4. */
  5. public interface Iterable<T> {
  6. /**
  7. * Returns an iterator over elements of type {@code T}.
  8. *
  9. * @return an Iterator.
  10. */
  11. Iterator<T>
  12. Iterator<T> iterator();
  13. default void forEach(Consumer<? super T> action) {
  14. Objects.requireNonNull(action);
  15. for (T t : this) {
  16. action.accept(t);
  17. }
  18. }
  19. default Spliterator<T> spliterator() {
  20. return Spliterators.spliteratorUnknownSize(iterator(), 0);
  21. }
  22. }

正如JDK注释里说的, 实现iterable接口的类可以使用“foreach”操作,然后并要求实现Iterator iterator()方法,该方法返回一个Iterator接口对象 ,所以使用这些集合时可以直接使用Iterator模式进行遍

  1. ArrayList<String> arrayList = new ArrayList<>();
  2. arrayList.add("a");
  3. arrayList.add("a");
  4. Iterator iterator = arrayList.iterator();

代码示例

UML类图如下
Iterator_UML类图.png

  1. /**
  2. * 要遍历的集合的接口,实现该接口的类将成为可以保存多个元素的集合
  3. */
  4. public interface Aggregate {
  5. public abstract Iterator iterator();
  6. }
  1. public class BookShelf implements Aggregate {
  2. private Book [] books ;
  3. private int last = 0;
  4. public BookShelf (int maxsize) {
  5. this.books = new Book[maxsize];
  6. }
  7. public Book getBookAt(int index) {
  8. return books[index];
  9. }
  10. public void appendBook (Book book) {
  11. this.books[last] = book ;
  12. last++;
  13. }
  14. public int getLength() {
  15. return last ;
  16. }
  17. @Override
  18. public Iterator iterator() {
  19. return new BookShelfIterator(this);
  20. }
  21. }
  1. /**
  2. * 用于遍历书架集合里的书
  3. */
  4. public class BookShelfIterator implements Iterator {
  5. private BookShelf bookShelf ;
  6. private int index ;
  7. public BookShelfIterator(BookShelf bookShelf) {
  8. this.bookShelf = bookShelf ;
  9. this.index = 0 ;
  10. }
  11. @Override
  12. public boolean hasNext() {
  13. if (index < bookShelf.getLength()) {
  14. return true;
  15. } else {
  16. return false;
  17. }
  18. }
  19. @Override
  20. public Object next() {
  21. Book book = bookShelf.getBookAt(index) ;
  22. index ++;
  23. return book;
  24. }
  25. }
  1. public class Book {
  2. private String name ;
  3. public Book (String name) {
  4. this.name = name ;
  5. }
  6. public String getName() {
  7. return name;
  8. }
  9. }
  1. /**
  2. *测试代码
  3. */
  4. public class Main {
  5. public static void main(String[] args) {
  6. BookShelf bookShelf = new BookShelf(5);
  7. bookShelf.appendBook(new Book("图解设计模式"));
  8. bookShelf.appendBook(new Book("Java编程思想"));
  9. bookShelf.appendBook(new Book("算法"));
  10. bookShelf.appendBook(new Book("TCP/IP协议:卷1"));
  11. Iterator iterator = bookShelf.iterator();
  12. while (iterator.hasNext()) {
  13. Book book = (Book) iterator.next();
  14. System.out.println(book.getName());
  15. }
  16. }
  17. }

核心代码主要是BookShelfIterator类实现Iterator接口并重写hasNext()和next()方法:hasNext()方法用于检测集合遍历的边界条件,而next()方法则像是遍历指针。