源码分析:逐行分析迭代器

介绍:在介绍Collection框架之前 先说明一下Collection框架中比较重要的一个概念 迭代
在Collection顶层接口里就继承了Iterable 所以所有的Collection集合容器都是可迭代的

概念:迭代的概念其实就是指 可以一个个的拿到集合容器中的元素
实现了Iterable接口的集合 就可以通过Iterator取出集合中的元素
实现了Iterable说明是可迭代的 而Iterator是迭代器 最终是通过迭代器取出集合中的元素

意义:我们并不是只能通过迭代器去遍历集合 只不过通过迭代器遍历集合能够解耦 把取数据这个操作交给迭代器 而不是我们直接去取数据 这样在后面如果需要更换集合类型的时候只需要满足迭代条件即可 实现数据访问和底层数据的分离 这个设计模式也叫做迭代器模式

注意:使用迭代器循环的时候不要用集合本身的添加和删除操作 否则会抛出ConcurrentModificationException异常
没有确认过 但是大部分的集合都有一个modCount属性用来记录集合做了多少次修改 在使用迭代器循环的时候会校验这个修改次数 如果有改变说明有修改
实现Iterable接口允许对象成为 for-each循环 语句的目标 (for-each 其实是Java提供的语法糖 实际上还是通过迭代器Iterator迭代遍历)

// 源代码
List<Integer> list = new ArrayList<>();
for (Integer i : list) {
    // 代码块
}

// 编译后的.class文件
List<Integer> list = new ArrayList();
Iterator var2 = list.iterator();
while(var2.hasNext()) {
    Integer i = (Integer)var2.next();
    // 代码块
}

源码:

  1. 可迭代:Iterable
    源码解析:

    Iterator<T> iterator();// 返回迭代器。
    default void forEach(Consumer<? super T> action) {// 就是一个for循环写法的包装
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
    default Spliterator<T> spliterator() {// 通过一个顺序遍历的Iterator对象获取一个并行遍历的Spliterator对象
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
    
  2. 迭代器:Iterator
    源码解析:

    // 迭代器的顶级接口 ==>>  Iterator
    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());
    }
    
  3. IterableIterator 之间的关系
    Iterable 的作用是用来标注当前容器可以使用迭代器遍历 它会返回一个迭代器Iterator
    Iterator 的作用才是迭代功能的实现
    Iterable是为了foreach循环设计的 Iterable表示集合可以返回Iterator对象 最终还是使用Iterator进行遍历。

  4. 也有人说为什么不直接将Iterator的功能整合到Iterable中?
    我看到的比较合理的解释是:有些集合类可能不止一种遍历方式 所以可能有不止一个的迭代器
    如:LinkedList实现了双向遍历和逆序遍历

posted @ 2021-08-06 17:11  熏晴微穗  阅读(29)  评论(0编辑  收藏  举报