0
点赞
收藏
分享

微信扫一扫

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


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

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

一、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​​实现类了。

获取编程资源

【JDK源码】Iterator与Iterable的实现与区别_迭代器_02


举报

相关推荐

0 条评论