想要遍历集合对象中的元素?迭代器模式为你提供了一个“旅行指南”,让你不暴露集合的内部结构,顺利地访问所有元素。

当我们面对一个庞大的数据集合时,直接操作每个元素显得有些麻烦,而且容易出错。就像是在一个大城市中旅游,如果没有地图和指南,我们可能会迷失在无尽的街道中。迭代器模式就像是你手中的旅行指南,帮助你安全、顺利地浏览整个城市(即集合)中的每个景点(即元素),而无需关心背后复杂的城市规划(即集合的内部实现)。它让你可以轻松访问集合中的元素,而不必暴露集合的具体实现。

趣味解读:城市旅行的“旅游导游”

想象你刚到一个陌生的城市,身边没有任何地图和标识。你需要一个导游来带领你参观每一个景点(元素)。这个导游不仅为你提供清晰的指引,还能告诉你该去哪儿、该停多久,无论你想访问哪个景点,只要跟着导游走就行了。你不需要知道城市的道路如何规划,你只需关注与导游的沟通即可。

这就是迭代器模式的作用!它帮助我们在集合中遍历元素,但对集合的内部实现完全不知情。我们只需要一个迭代器对象,指引我们通过集合中的每一个元素,轻松高效。

Java代码案例:迭代器模式 - 简单的书架管理

假设我们有一个书架,书架上有不同的书,每本书都有标题和作者。我们需要遍历这些书,但不想直接操作书架的内部结构。此时,迭代器模式派上了用场。

// 1. 书的类
class Book {
    private String title;
    private String author;
​
    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }
​
    public String getTitle() {
        return title;
    }
​
    public String getAuthor() {
        return author;
    }
​
    @Override
    public String toString() {
        return "书名: " + title + ", 作者: " + author;
    }
}
​
// 2. 迭代器接口
interface Iterator {
    boolean hasNext();
    Object next();
}
​
// 3. 书架接口
interface BookShelf {
    void addBook(Book book);
    Iterator createIterator();
}
​
// 4. 具体书架实现
class MyBookShelf implements BookShelf {
    private Book[] books;
    private int last = 0;
​
    public MyBookShelf(int size) {
        books = new Book[size];
    }
​
    @Override
    public void addBook(Book book) {
        if (last < books.length) {
            books[last] = book;
            last++;
        }
    }
​
    @Override
    public Iterator createIterator() {
        return new BookShelfIterator(books);
    }
}
​
// 5. 具体迭代器实现
class BookShelfIterator implements Iterator {
    private Book[] books;
    private int index = 0;
​
    public BookShelfIterator(Book[] books) {
        this.books = books;
    }
​
    @Override
    public boolean hasNext() {
        return index < books.length && books[index] != null;
    }
​
    @Override
    public Object next() {
        return books[index++];
    }
}
​
// 6. 客户端代码
public class Main {
    public static void main(String[] args) {
        BookShelf bookShelf = new MyBookShelf(5);
        bookShelf.addBook(new Book("《Java编程思想》", "Bruce Eckel"));
        bookShelf.addBook(new Book("《设计模式:可复用面向对象软件的基础》", "Erich Gamma"));
        bookShelf.addBook(new Book("《算法导论》", "Thomas H. Cormen"));
​
        // 使用迭代器遍历书架上的书籍
        Iterator iterator = bookShelf.createIterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

解析:

  • 书籍类Book 类包含书的基本信息,如书名和作者。

  • 迭代器接口Iterator 接口定义了两个方法:hasNext() 用来判断是否还有下一个元素,next() 返回当前元素并指向下一个元素。

  • 书架接口BookShelf 接口包含两个方法:addBook() 用来添加书籍,createIterator() 用来创建一个迭代器。

  • 具体书架实现MyBookShelf 类实现了 BookShelf 接口,内部维护一个 Book 数组,并且可以返回一个迭代器来遍历书架上的书籍。

  • 具体迭代器实现BookShelfIterator 实现了 Iterator 接口,负责遍历书架上的书籍。

运行结果:

书名: 《Java编程思想》, 作者: Bruce Eckel
书名: 《设计模式:可复用面向对象软件的基础》, 作者: Erich Gamma
书名: 《算法导论》, 作者: Thomas H. Cormen

实际应用场景:

  1. 集合遍历:最常见的应用场景是遍历集合对象。通过使用迭代器模式,我们可以避免直接暴露集合的实现方式,只关心遍历过程。

  2. 文件系统遍历:在一些文件管理系统中,用户可能需要遍历文件夹中的文件。迭代器模式可以用来定义一个通用的文件遍历方式,使得不同的文件系统结构能够方便地进行迭代。

  3. GUI组件的遍历:在一些图形化界面中,可能有多个组件需要依次进行操作。迭代器模式可以使得我们在不暴露组件内部结构的情况下,依次操作每个组件。

总结:

迭代器模式通过为集合提供统一的遍历接口,避免了直接暴露集合的实现结构,让我们可以灵活地访问和操作集合中的元素。它使得集合的遍历变得更加简单和安全,同时也提升了代码的可维护性和扩展性。无论是在处理数据、文件还是UI组件时,迭代器模式都是一种非常有效的设计模式。