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

迭代器模式

💻 迭代器模式 (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. 复杂性增加:对简单的数据结构来说,使用迭代器模式可能会使代码更加复杂。

适用场景

  • 遍历复杂数据结构:如树、图、链表等。迭代器可以隐藏这些数据结构的复杂性。
  • 需要统一遍历接口的地方:例如在一个框架或库中,不同的数据结构都需要通过相同的接口遍历。
  • 需要多种遍历方式:如从前到后、从后到前等,迭代器可以轻松扩展不同的遍历方式。
相关推荐
_院长大人_7 分钟前
Spring Boot 客户端设计示例:自动刷新 Token 并重试接口调用(Springboot Starter 封装)
java·spring boot·后端
卷到起飞的数分14 分钟前
19.Spring Boot原理1
java·spring boot·后端
消失的旧时光-194316 分钟前
彻底理解 synchronized:实例锁、类锁与自定义锁的原理和最佳实践
java·开发语言
鹿里噜哩16 分钟前
Spring Authorization Server 打造认证中心(二)自定义数据库表
spring boot·后端·kotlin
开源之眼27 分钟前
github star 较多的Java双亲委派机制【类加载的核心内容加星】
java
编程火箭车29 分钟前
【Java SE 基础学习打卡】19 运算符(中)
java·java入门·运算符·编程基础·赋值运算符·复合赋值·自增自减
是一个Bug29 分钟前
Spring事件监听器源码深度解析
java·数据库·spring
蜂蜜黄油呀土豆33 分钟前
ThreadLocal 深度解析:它解决了什么、原理是什么、如何正确使用(含代码与实战建议)
java·并发编程·内存泄漏·threadlocal
v***870437 分钟前
Spring Boot实现多数据源连接和切换
spring boot·后端·oracle
毕设源码-郭学长38 分钟前
【开题答辩全过程】以 高校教室管理系统为例,包含答辩的问题和答案
java·spring boot