本文源码基于JDK1.7
Iterable获取迭代器接口
Iterable接口中只有一个iterator方法,用来获取迭代器
package java.lang;
import java.util.Iterator;
public interface Iterable<T> {
Iterator<T> iterator();
}
Iterator迭代器行为定义接口
迭代器定义接口,有三个抽象方法
hashNext():获取下一个元素
next():遍历到下一个接口
remove():移出当前遍历到的元素
package java.util;
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
java集合中的迭代器
ArrayList相关类图
Collection接口继承Iterable接口同时也继承了iterator方法,
public interface Collection<E> extends Iterable<E>
List接口继承Collection接口同时也继承了iterator方法
public interface List<E> extends Collection<E>
实现类ArrayList实现了List接口,具体实现了iterator方法
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable
在学习ArrayList中的iterator方法之前,我们首先要学习ArrayList中的一些变量,这样方便我们理解iterator方法的源码
modCount:该变量定义在AbstractList当中,默认初始化为0,被protected修饰能被子类访问同时不能被序列化,用于,ArrayList继承了AbstractList,便继承了其中的成员变量modCount,也就是修改次数。
protected transient int modCount = 0;
ArrayList中iterator方法返回的迭代器实例是ArrayList的内部私有类Itr实例化返回的
Itr私有类中使用cursor、lastRet来标识迭代元素,cursor总是指向当前迭代将操作元素的下一个元素的位置,而lastRet指向cursor的上一个位置,next和remove操作的均是lastRet位置上的元素,使用expectedModCount来进行并发控制,确保同一时间只有一个迭代器对集合进行操作,但是我们不能完全依赖迭代器的快速失败机制来做线程安全控制。
public Iterator<E> iterator() {
return new ArrayList.Itr();
}
private class Itr implements Iterator<E> {
//游标,指向当前迭代到的元素,作为成员变量初始化为0
int cursor;
//当前迭代到的元素的上一个元素
int lastRet;
//期望的修改次数,作为成员变量初始化为0
int expectedModCount;
private Itr() {
this.lastRet = -1;
//将期望修改次数初始化为当前ArrayList的修改次数
this.expectedModCount = ArrayList.this.modCount;
}
//判断当前迭代器是否还有下一个元素
public boolean hasNext() {
//通过当前游标与当前ArrayList的大小来判断是否还有下一个元素
return this.cursor != ArrayList.this.size;
}
//返回迭代器的下一个元素
public E next() {
//快速失败检查
this.checkForComodification();
//赋值var1为当前游标
int var1 = this.cursor;
//若当前游标大于等于当前ArrayList的大小
if (var1 >= ArrayList.this.size) {
//抛出无此元素错误
throw new NoSuchElementException();
} else {
//否则获取到当前ArrayList的内置数组
Object[] var2 = ArrayList.this.elementData;
//再一次判断了游标是否大于等于ArrayList数组长度
if (var1 >= var2.length) {
throw new ConcurrentModificationException();
} else {
//将游标+1
this.cursor = var1 + 1;
//lastRet赋值为游标的前一个元素的下标,且返回游标的前一个元素
return var2[this.lastRet = var1];
}
}
}
//删除当前迭代到的元素
public void remove() {
//如果lastRet小于0,有两种情况,1:Itr中被初始化为-1;2:Itr中remove后没有next
if (this.lastRet < 0) {
throw new IllegalStateException();
} else {
//快速失败检查
this.checkForComodification();
try {
//调用ArrayList中的remove方法来移出lastRet位置上的元素
ArrayList.this.remove(this.lastRet);
//当lastRet下标的元素被删除,游标移到lastRet位置
this.cursor = this.lastRet;
//再将lastRet赋值为-1,如果下一次remove之前没有进行next操作,则报错
this.lastRet = -1;
//期望修改次数等于ArrayList的修改次数,ArrayList中remove方法中会将modCount+1,在Itr中的remove方法中,保证expectedModCount等于modCount,这样快速失败检查不会报错
this.expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException var2) {
throw new ConcurrentModificationException();
}
}
}
//快速失败检查,通过比较modCount和expectedModCount来判断
final void checkForComodification() {
if (ArrayList.this.modCount != this.expectedModCount) {
throw new ConcurrentModificationException();
}
}
}
//ArrayList中的remove方法
public E remove(int var1) {
//有效范围判断
this.rangeCheck(var1);
//修改次数+1
++this.modCount;
//获取到要删除的元素
Object var2 = this.elementData(var1);
int var3 = this.size - var1 - 1;
if (var3 > 0) {
//使用System.arraycopy来截取数组,达到删除元素的效果
System.arraycopy(this.elementData, var1 + 1, this.elementData, var1, var3);
}
//释放数组空间
this.elementData[--this.size] = null;
return var2;
}