深入探索迭代器模式的原理与应用

迭代器模式

💻 迭代器模式 (Iterator Pattern) 是一种行为设计模式,它允许你顺序访问一个集合对象中的元素,而无需暴露其底层表示。在不同的数据结构中,如数组、链表或其他集合,它可以统一提供一种方式来逐个遍历这些元素。

主要组成部分和UML类图

  1. Iterator 接口 :定义遍历元素所需要的操作,如 hasNext()next().
  2. ConcreteIterator 具体迭代器 :实现 Iterator 接口,负责具体遍历操作。
  3. Aggregate 聚合接口 :提供创建迭代器的方法 createIterator().
  4. ConcreteAggregate 具体聚合类:实现聚合接口,包含实际元素集合,并返回迭代器实例。

生动案例理解:图书馆书架

情景:你走进图书馆,看到有许多不同的书架,每个书架有一排书。你想要逐一遍历每本书,但图书馆有不同种类的书架,它们的排列规则不同。使用迭代器模式,你可以通过同一个接口来遍历所有的书架,而无需关心每个书架的具体实现。

代码实现迭代器模式

让我们实现一个书架例子。书架有不同的书,通过迭代器,我们可以按顺序遍历这些书。

Step 1:定义书的类

java 复制代码
lass Book {
    private String name;

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

    public String getName() {
        return name;
    }
}

作用 : 定义书的属性和构造函数,通过getName()方法可以获取书名。

Step 2:创建迭代器接口

java 复制代码
interface BookIterator extends Iterator<Book> {
    boolean hasNext();
    Book next();
}

作用 : 定义迭代器的接口,提供了hasNext()next()方法,用于遍历书籍。

Step 3: 具体的迭代器实现

java 复制代码
// 第三步:具体迭代器实现类
class ShelfIterator implements BookIterator {
    private List<Book> books;
    private int position = 0;

    public ShelfIterator(List<Book> books) {
        this.books = books;
    }

    @Override
    public boolean hasNext() {
        return position < books.size();
    }

    @Override
    public Book next() {
        return books.get(position++);
    }
}

作用 : ShelfIterator是迭代器的具体实现类,内部维护了当前遍历的位置并提供具体的遍历实现

Step 4: 定义聚合接口

java 复制代码
// 第四步:抽象聚合接口
interface BookShelf {
    BookIterator createIterator();
}

作用: 定义了一个抽象聚合接口,用于创建一个新的迭代器。

Step 5: 实现具体聚合类

java 复制代码
// 第五步:具体聚合实现类
class LibraryShelf implements BookShelf {
    private List<Book> books;

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

    public void addBook(Book book) {
        this.books.add(book);
    }

    @Override
    public BookIterator createIterator() {
        return new ShelfIterator(books);
    }
}

作用 : LibraryShelf是具体的聚合类,管理书籍的集合,并提供创建迭代器的方法。

Step 6: 测试类

java 复制代码
// 第六步:测试类
public class Main {
    public static void main(String[] args) {
        LibraryShelf shelf = new LibraryShelf();
        shelf.addBook(new Book("Effective Java"));
        shelf.addBook(new Book("Design Patterns"));
        shelf.addBook(new Book("Clean Code"));

        BookIterator iterator = shelf.createIterator();

        System.out.println("Traversing the book shelf:");
        while (iterator.hasNext()) {
            Book book = iterator.next();
            System.out.println("Book: " + book.getName());
        }
    }
}

输出结果

java 复制代码
Traversing the book shelf:
Book: Effective Java
Book: Design Patterns
Book: Clean Code

通过这个案例,你可以看到迭代器模式如何解耦聚合对象和遍历逻辑,使得可以以统一的方式遍历不同的集合。

JDK源码中的应用

在JDK中,迭代器模式广泛用于Collection框架,特别是在ListSetMap等数据结构中。让我们看看几个常见的示例:

java.util.Iterator

java 复制代码
public interface Iterator<E> {
    boolean hasNext();
    E next();
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
}

应用 : Iterator接口是Java集合框架中的迭代器标准接口。几乎所有的集合类(ArrayList, HashSet, LinkedList)都实现了这个接口,用于提供遍历方法。

java.util.ArrayList 的迭代器实现

java 复制代码
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    // ArrayList中的内部类实现了Iterator
    private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such

        public boolean hasNext() {
            return cursor != size();
        }

        public E next() {
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            // 删除操作
        }
    }

    public Iterator<E> iterator() {
        return new Itr();
    }
}

应用场景 : ArrayListiterator() 方法返回的是内部类 Itr 的实例,Itr 实现了 Iterator 接口,通过 hasNext()next() 方法来遍历 ArrayList 中的元素。

迭代器模式总结

优点🟢

  1. 解耦集合与遍历:可以在不暴露集合内部表示的前提下遍历集合。
  2. 统一遍历接口:无论集合的类型或内部实现如何,迭代器提供了一致的遍历接口。
  3. 开闭原则:可以很容易地在不修改集合类的情况下扩展新类型的迭代器。
  4. 单一职责:将遍历逻辑从集合类中分离出来,简化了集合类的职责。

缺点 🔴

  1. 性能开销:迭代器模式通常需要额外的类来实现,可能会导致开销增加,尤其是对于大量的小型对象。
  2. 复杂性增加:对简单的数据结构来说,使用迭代器模式可能会使代码更加复杂。

适用场景

  • 遍历复杂数据结构:如树、图、链表等。迭代器可以隐藏这些数据结构的复杂性。
  • 需要统一遍历接口的地方:例如在一个框架或库中,不同的数据结构都需要通过相同的接口遍历。
  • 需要多种遍历方式:如从前到后、从后到前等,迭代器可以轻松扩展不同的遍历方式。
相关推荐
Flittly几秒前
【SpringAIAlibaba新手村系列】(9)Text to Image 文本生成图像技术
java·spring boot·agent
Flittly1 分钟前
【SpringAIAlibaba新手村系列】(10)Text to Voice 文本转语音技术
java·spring boot·agent
JoshRen4 分钟前
springboot之集成Elasticsearch
spring boot·后端·elasticsearch
诸葛大钢铁5 分钟前
Java实现Excel文件合并
java·windows·excel
黎明丶之前8 分钟前
Spring Cloud Gateway 升级与 Bucket4j 限流实践
java·spring cloud
程序员木圭13 分钟前
05-告别逻辑混乱!Java 流程控制让代码学会"判断和循环"
java·后端
MmeD UCIZ17 分钟前
Skywalking介绍,Skywalking 9.4 安装,SpringBoot集成Skywalking
spring boot·后端·skywalking
ward RINL17 分钟前
Spring boot启动原理及相关组件
数据库·spring boot·后端
yaaakaaang17 分钟前
三、抽象工厂模式
java·抽象工厂模式
kongba00718 分钟前
复刻 Claude Code 项目御马术缰绳系统 harness engineering 落地蓝图
java·linux·服务器