迭代器模式在JDK源码中的应用
本节主要介绍迭代器模式在 JDK 源码中的应用。
<<interface>> Iterator 是 Java 提供的迭代器,可以让某个序列实现该接口来提供标准的 Java 迭代器。也就是说,实现 Iterator 接口就相当于“使用”一个迭代器。
Iterator 接口源码如下。
另外,我们在学习组合模式时见过 remove() 方法。可以看出迭代器模式和组合模式两者存在一定的相似性,组合模式解决的是统一树形结构各层次访问接口,迭代器模式解决的是统一各集合对象元素遍历接口。虽然它们的适配场景不同,但核心理念是相同的。
接着来看 Iterator 的实现类,以 ArrayList 为例。ArrayList 实现了 List 接口,List 接口继承了 Collection 接口,Collection 接口继承了 Iterable 接口,Iterable 接口中包含了一个 iterator( ) 方法,因此 ArrayList 就需要实现该 iterator( ) 方法。该方法的实现很简单,就是返回一个实现了 Iterator 接口的迭代器实例。
ArrayList 类中的迭代器是以内部类的形式实现的,由于内部类可以直接访问外部类的成员变量,所以该迭代器内部类可以很方便地实现 Iterator 接口中的 hasNext( ) 和 next( ) 方法。ArrayList 中的迭代器内部类名字是 Itr,源码如下所示:
在 ArrayList 内部还有几个迭代器对 Itr 进行了进一步扩展,首先看 ListItr。
注意:由于篇幅原因,这里没有列出 ArrayList 中其它几个内部类对 Itr 的进一步扩展,感兴趣的小伙伴可以阅读 ArrayList 类的完整代码。
<<interface>> Iterator 是 Java 提供的迭代器,可以让某个序列实现该接口来提供标准的 Java 迭代器。也就是说,实现 Iterator 接口就相当于“使用”一个迭代器。
Iterator 接口源码如下。
public interface Iterator<E> {
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());
}
}
从上面代码可以看出,Iterator 接口定义了一些需要子类实现的方法和默认方法。其中包含了两个主要方法,即 hasNext() 和 next() 方法。代码中两个 default 方法是 JDK 1.8 之后才有的接口新特性。JDK 1.8 版本之前接口中不能有方法实体。另外,我们在学习组合模式时见过 remove() 方法。可以看出迭代器模式和组合模式两者存在一定的相似性,组合模式解决的是统一树形结构各层次访问接口,迭代器模式解决的是统一各集合对象元素遍历接口。虽然它们的适配场景不同,但核心理念是相同的。
接着来看 Iterator 的实现类,以 ArrayList 为例。ArrayList 实现了 List 接口,List 接口继承了 Collection 接口,Collection 接口继承了 Iterable 接口,Iterable 接口中包含了一个 iterator( ) 方法,因此 ArrayList 就需要实现该 iterator( ) 方法。该方法的实现很简单,就是返回一个实现了 Iterator 接口的迭代器实例。
ArrayList 类中的迭代器是以内部类的形式实现的,由于内部类可以直接访问外部类的成员变量,所以该迭代器内部类可以很方便地实现 Iterator 接口中的 hasNext( ) 和 next( ) 方法。ArrayList 中的迭代器内部类名字是 Itr,源码如下所示:
package java.util;
import java.util.function.Consumer;
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
...
transient Object[] elementData;
private int size;
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
...
}
...
}
Itr 是 ArrayList 中实现了 Iterator 接口的内部类,且在实现 hasNext() 和 next() 方法时,可以很方便地访问 ArrayList 的成员变量 size 和 elementData 数组。在 ArrayList 内部还有几个迭代器对 Itr 进行了进一步扩展,首先看 ListItr。
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index;
}
public boolean hasPrevious() {
return cursor != 0;
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
...
}
ListItr 内部类增加了 hasPrevious() 方法,主要用于判断是否还有上一个元素。另外,还有 SubList 对子集合的迭代处理。注意:由于篇幅原因,这里没有列出 ArrayList 中其它几个内部类对 Itr 的进一步扩展,感兴趣的小伙伴可以阅读 ArrayList 类的完整代码。
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算