迭代器设计模式
1. 简单介绍
迭代器设计模式(Iterator)是一种结构型设计模式。该模式提供一种方法顺序访问一个聚合对象(如:
JDK中
的容器对象ArrayList
等)中各个元素,而又不暴露该对象的内部表示。
2. 使用场景
- 按顺序访问访问聚合对象(容器)中包含的内部对象
3. 场景举例
JDK
中的常见的容器对象,如:ArrayList
、LinkedList
,在设计上都融入了迭代器设计模式的思想,为调用者提供统一的、顺序遍历容器中的元素的功能。
4. UML类图
5. 具体实现
描述
- 背景:实现一个简易版的ArrayList,通过迭代器遍历元素
- 说明:各个类的功能同JDK中的类作用类似
代码实现
List_.java
/**
* List_:集合接口
*/
public interface List_<E> {
/**
* 获取集合的迭代器对象
*/
Iterator_<E> iterator();
/**
* 添加元素
*/
void add(E e);
}
Iterator_.java
/**
* Iterator_:可迭代接口
*/
public interface Iterator_<E> {
/**
* 下个元素是否存在
*/
boolean hasNext();
/**
* 取出下个元素
*/
E next();
}
ArrayList_.java
/**
* _ArrayList:自定义ArrayList
*/
public class ArrayList_<E> implements List_<E> {
private Object[] ele;
private int size;
@Override
public Iterator_<E> iterator() {
return new MyIterator();
}
/**
* 具体的迭代器使用内部类实现,可以访问到ele数组的size等私有属性
*/
private class MyIterator implements Iterator_<E> {
int cursor = 0;
@Override
public boolean hasNext() {
return cursor < ele.length;
}
@Override
public E next() {
return (E) ele[cursor++];
}
}
@Override
public void add(E e) {
if (ele == null || ele.length <= 0) {
ele = new Object[0];
}
Object[] newEle = new Object[size + 1];
System.arraycopy(ele, 0, newEle, 0, size);
newEle[size++] = e;
ele = newEle;
}
public int getSize() {
return size;
}
}
Client.java
/**
* Client:客户端
*/
public class Client {
public static void main(String[] args) {
List_<Integer> list = new ArrayList_<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
// 迭代器遍历list中的元素
Iterator_<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
7. 源码展示
JDK
源码中的ArrayList
提供了迭代器供调用者便利其存放的元素。其中迭代器模式的ConcreteIterator
迭代器具体实现类,为ArrayList
的内部类,单独针对ArrayList
实现其特有的元素遍历方式,具体代码如下:
Iterator.java
/**
* 对应迭代器模式中的Iterator角色
* 规范了容器对象统一的迭代接口
*/
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
}
Collection
/**
* 对应迭代器模式中的Aggregate角色
*/
public interface Collection<E> {
Iterator<E> iterator();
}
ArrayList.java
/**
* 对应迭代器模式中的ConcreteAggregate角色,其中List继承了Collection接口
* 具体的聚合对象,存放元素
*/
public class ArrayList<E> implements List<E> {
/**
* Itr类对应迭代器模式中的ConcreteIterator角色
* 内部类的形式,完成具有遍历ArrayList功能的具体的迭代器的实现
*/
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];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}