行为型模式,已被集成在使用的各种编程语言中,java的forEach语句就使用了迭代器模式,Iterable和Iterator为迭代器模式的实现。

【DP】定义

提供一种方法顺序访问一个聚合对象中的各个元素,而又不是暴露该对象的内部表示。

Java使用场景

Collection接口继承Iterable, Collection的子类都分别实现自己的Iterator

Iterator中主要的两个方法:

1
2
3
4
5
public interface Iterator<E> {
boolean hasNext();
E next();
...
}

举例: ArrayList中的Itr:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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; // 期待的ModeCount,控制并发修改

public boolean hasNext() {
// 当前位置不等于list大小,则还有下一个元素可以使用
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 {
// 移除元素做法是: 将lastRet后的元素拷贝到lastRet位置,然后将最后一个置null,让gc回收
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
// modCont全局维护,如果不等于expectedModCount,说明有人改过了
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
...
}

后记

Iterator提供了一种遍历元素的接口,ArrayList是按照顺序去取的,这也给我们提供了一种思路,当有复杂遍历顺序时(比如数据有层次关系时,需要按照深度优先遍历),可以自定义迭代器实现。