vlambda博客
学习文章列表

【JDK源码】Iterator与Iterable的实现与区别

JAVA

本/文/前/言

JAVA

1. 在介绍Iterator与Iterable接口之前,需要了解Iterator与Iterable接口在Java类库家族谱中的地位。如下图0-1所示。


一、Iterable接口的地位

    如图0-1所示,Iterable接口是List、Set、Collection的最高父类接口。


    而iterator为Java中的迭代器对象,是能够对List这样的集合进行迭代遍历的底层依赖。iterable接口里定义了返回iterator的方法,相当于对iterator的封装,同时实现了iterable接口的类可以支持forEach循环。


综上:


1.Iterable接口是各Java类集框架的最高级接口;

2.iterator接口作为Iterable接口中一个方法的返回类型。


二、iterator接口的内部方法

public interface Iterator<E> { //如果仍有元素可以迭代,则返回 true。 boolean hasNext();  //返回迭代的下一个元素。 E next();  //对迭代器剩下还未迭代的元素遍历,用lamda表达式。  default void forEachRemaining(Consumer<? super E>   action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); } }

    Iterator是一个“迭代器”的概念,无论是在JavaScript语言、Java语言或是jQuery框架都是一种底层支撑,Iterator迭代器中的方法类似数据库查询结果对象中的“游标”。

//如果仍有元素可以迭代,则返回 true。boolean hasNext();

    判断“迭代器”对象中,是否有下一个元素可以迭代。

//返回迭代的下一个元素。E next();

    返回“迭代器”对象中的下一个元素。

 //对迭代器剩下还未迭代的元素遍历,用lamda表达式。 default void forEachRemaining(Consumer<? super E>  action) {  Objects.requireNonNull(action);  while (hasNext())  action.accept(next()); }

    用lamda表达式对迭代器剩下还未迭代的元素遍历。用关键字default修饰接口中的方法,可以定义方法体。


三、iterable接口的内部方法

public interface Iterable<T> { //返回一个在一组 T 类型的元素上进行迭代的迭代器。 Iterator<T> iterator(); //用lamda表达式进行forEach遍历迭代器  default void forEach(Consumer<? super T>  action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); }  }}

    Iterable在方法中返回“迭代器”的Iterator对象。


四、Iterable与Iterator关系

    为什么不直接把Iterator接口中的hasNext(),next()等方法放在Iterable接口中,其他类直接实现Iterable接口就可以了?JDK的写法是否是多此一举?

非也!



    原因是有些集合类可能不止一种遍历方式,实现了Iterable的类可以再实现多个Iterator内部类,例如LinkedList中的ListItr和DescendingIterator两个内部类,就分别实现了双向遍历和逆序遍历。通过返回不同的Iterator实现不同的遍历方式,这样更加灵活。如果把两个接口合并,就没法返回不同的Iterator实现类了。