迭代器模式

迭代器模式主要的作用是遍历元素的同时,将其内部元素隐藏,不对外暴露。其抽象了相关访问容器中元素的方法。一般来说迭代器模式的实现和容器的实现不是紧密耦合的,它们是独立实现的,迭代器模式的实现不依赖于容器的具体实现。

在Java中,迭代器模式有具体的接口:

public interface Iterable<T> {

    Iterator<T> iterator();

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}
Iterable接口声明了三个方法:iterator()、forEach(Consumer<? super T> action)、spliterator(),分别是获取迭代器、for-each loop 增强、可拆分迭代器。
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

其中的forEach()方法里的for(T t : this)是个语法糖,前提是this是继承了Iterable接口,编译后:

for (Iterator<T> iter = this.iterator(); iter.hasNext(); ) {
    T t = iter.next();
    ...
}

具体可见:https://stackoverflow.com/questions/59440255/why-does-fort-t-this-work-and-what-does-it-mean

在Java里,迭代器模式核心接口有:Iterable和Iterator。Iterable表示容器是可迭代的,并提供迭代器;Iterator是迭代器的抽象接口,提供遍历容器元素的方法。

 Collection接口继承了Iterable<T>,表明其是可迭代的,其实现类必须要实现Iterable<T>中的方法,且其iterator()方法返回的Iterator接口也必须要有具体的实现;实际上,在AbtractList抽象类里已经有Iterator接口的实现类,从这里可以看出,迭代器模式的迭代实现是和容器实现分离的。

Collection接口有多个继承或实现,为何ArrayList(甚至其父类AbstractList)中要自己实现Iterator接口呢,原因可能在于特殊处理,看具体的源码即可了解。

Iterator接口声明如下:

public interface Iterator<E> {

    boolean hasNext();

    E next();

    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

主要有判断是否有下个元素(hasNext())、下一个元素(next())、移除(remove())、forEach增强(forEachRemaining())。

posted @ 2023-06-30 17:32  朝云出岫  阅读(17)  评论(0)    收藏  举报