JDK源码阅读之Iterator接口

Iterator接口介绍

对 collection 进行迭代的迭代器。迭代器取代了 Java Collections Framework 中的 Enumeration。Iterator接口也是集合类的顶级接口,全部的集合类都会实现这个接口,直接或间接。

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());
    }
}

public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

Iterator的前身

Iterator迭代器取代了 Java Collections Framework 中的 Enumeration。
为什么要取代?官方给出的原因是:

  1. 迭代器允许调用者利用定义良好的语义在迭代期间从迭代器所指向的 collection 移除元素。
  2. 方法名称得到了改进。

通俗点来说就是增加了remove方法和方法名得到了改善(没有这么擦长了)

Iterator与Iterable

Iterator和Iterable都是接口。 但是Iterable中有个iterator()方法可以产生Iterator类型的接口,而且大部分接口都是直接实现Iterable接口。

为什么不直接实现iterator

因为Iterator接口的核心方法next()或者hasNext() 是依赖于迭代器的当前迭代位置的。 如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。 当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。 除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。但即时这样,Collection也只能同时存在一个当前迭代位置,而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器,多个迭代器是互不干扰的。

Iterator的错误

fail-fast 机制

fail-fast机制在遍历一个集合时,当集合结构被修改,会抛出Concurrent Modification Exception。
fail-fast会在以下两种情况下抛出ConcurrentModificationException

  1. 单线程环境
    集合被创建后,在遍历它的过程中修改了结构。
  2. 多线程环境
    当一个线程在遍历这个集合,而另一个线程对这个集合的结构进行了修改。

fail-safe机制

fail-safe任何对集合结构的修改都会在一个复制的集合上进行修改,因此不会抛出ConcurrentModificationException
fail-safe机制有两个问题

  1. 需要复制集合,产生大量的无效对象,开销大
  2. 无法保证读取的数据是目前原始数据结构中的数据。

迭代器模式

迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。

阅读感受

这个接口主要讲的是思想,主要是实现一个迭代器。

说明

文章是本人在看完多篇相关博文后,加上自己的的理解写出来的,本文代表本人观点,如有错误或不同意见,请留言或者联系我:zlh8013gsf@126.com

感谢以下博文:

JDK文档
Java 集合源码解析(1):Iterator.
Java中Iterator与Iterable的区别.

©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页