本文主要讲解迭代器模式在ArrayList源码中的使用。
迭代器模式(Iterator Pattern):提供一种方法来访问聚合对象中的各个元素,而不用暴露这个对象的内部表示。在Java中,ArrayList的迭代器有两种:Iterator和ListIterator。
Iterator
迭代器是一个用来遍历并选择序列中的对象。Java的Iterator的只能单向移动。
例子
在写如何实现之前,先看一个使用迭代器Iterator的小例子:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test {
@org.junit.Test
public void test() {
List list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String str = (String) iterator.next();
System.out.println(str);
iterator.remove();
}
System.out.println(list.size());
}
}
运行结果
1
2
3
4
0
方法
- iterator(),list.iterator()用来从容器对象中返回一个指向list开始处的迭代器。
- next(),获取序列中的下个元素。
- hasNext(),检查序列中向下是否还有元素。
- remove(),将迭代器最近返回的一个元素删除。这也意味着调用remove()前需要先调用next()。
实现
在设计模式(16)-迭代器模式这一文章中曾讲过,迭代器模式中有四个角色:
- 抽象聚合类Aggregate。在ArrayList的Iterator迭代器实现中,没有抽象聚合类。虽然它实现了AbstractList,实现了List,但它向外部提供的创建迭代器的方法iterator()是它自己的。
- 具体聚合类ConcreteAggregate。在ArrayList的Iterator迭代器实现中,指的是ArrayList。
- 抽象迭代器Iterator。在ArrayList的Iterator迭代器实现中,指的是Iterator接口。
- 具体迭代器ConcreteIterator。在ArrayList中的Iterator迭代器实现中,指的是Itr。
ArrayList代码片段
public class ArrayList<E>
{
/**
* 保存添加到ArrayList中的元素。
* ArrayList的容量就是该数组的长度。
* 该值为DEFAULTCAPACITY_EMPTY_ELEMENTDATA 时,当第一次添加元素进入ArrayList中时,数组将扩容值DEFAULT_CAPACITY。
* 被标记为transient,在对象被序列化的时候不会被序列化。
*/
transient Object[] elementData;
// ArrayList的实际大小(数组包含的元素个数)。
private int size;
/**
* 返回一个用来遍历ArrayList元素的Iterator迭代器
*/
public Iterator<E> iterator() {
return new Itr();
}
/**
* AbstractList.Itr的最优化的版本
*/
private class Itr implements Iterator<E> {
int cursor; // 下一个要返回的元素的索引
int lastRet = -1; // 最近的被返回的元素的索引; 如果没有返回-1。
int expectedModCount = modCount;
/**
* 判断是否有下一个元素
*/
public boolean hasNext() {
//如果下一个要返回的元素的索引不等于ArrayList的实际大小,则返回false
return cursor != size;
}
/**
* 返回下一个元素
*/
@SuppressWarnings(