源码分析:逐行分析迭代器
介绍:在介绍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();
// 代码块
}
源码:
-
可迭代: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); }
-
迭代器: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()); }
-
Iterable 和 Iterator 之间的关系
Iterable 的作用是用来标注当前容器可以使用迭代器遍历 它会返回一个迭代器Iterator
Iterator 的作用才是迭代功能的实现
Iterable是为了foreach循环设计的 Iterable表示集合可以返回Iterator对象 最终还是使用Iterator进行遍历。
-
也有人说为什么不直接将Iterator的功能整合到Iterable中?
我看到的比较合理的解释是:有些集合类可能不止一种遍历方式 所以可能有不止一个的迭代器
如:LinkedList实现了双向遍历和逆序遍历