Iterator(java.util)
- 在Java中对集合有3种遍历方式
- 普通的for循环
- 迭代器(iterator)遍历
- for each循环
Iterator
为 Java 中的迭代器对象,该接口封装了hashNext()/next()/remove()/forEachRemaining()(1.8)
方法,对集合进行遍历的底层依赖,Iterable
(java.lang) 接口是所有Collection
类的父接口,内部封装了Iterator
迭代器对象,因此集合类可以使用迭代器遍历元素。forEach
内部也是依赖于迭代器,自jdk1.8开始,为Iterable
接口中添加了默认方法forEach
,即实现该接口时,可以直接调用forEach
的增强for循环,Lambda进一步减少了模板代码。默认的spliterator()
方法为遍利和分割元素提供更便捷操作
Iterable 与 Iterator 关系
- 集合类扩展了
Iterable 接口
并返回iterator
接口的实例,好处是一个集合可以再实现多个不同的Iterator
内部类,更多样的迭代规则,集合更灵活。如LinkedList中的ListItr和DescendingIterator两个内部类,就分别实现了双向遍历和逆序遍历。通过返回不同的Iterator实现不同的遍历方式,这样更加灵活。如果把两个接口合并,就没法返回不同的Iterator实现类了。
注意
- 所有实现
Iterator
接口的子类,如果想要查看集合中的所有子类元素应该先调用hashNext():boolean
方法,返回true时,才能反复调用next():E
方法 - 调用
remove()
方法,它会返回上一个调用next()方法的对象的引用,即remove()方法实际上删除集合中的一个元素是先用next()方法跳过元素然后进行删除的。如果删除两个相邻的元素,正确步骤 remove();next();remove()
重复步骤太多,因此在jdk1.8版本在接口中提供了forEachRemaining()
方法 forEachRemaining()
方法提供了null值判断,封装了hashNext()与next()
方法,利用Lambda表达式进行函数式接口调用,可以在任何类中直接使用更简洁的语法对元素进行访问操作。Lambda 大法 NBdefault void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); }