类图
定义
提供一种方法访问一个容器对象中各个元素,而又不需要暴露该对象的内部细节
优点
- 它支持以不同的方式遍历一个聚合对象。
- 迭代器简化了聚合类。
- 在同一个聚合上可以有多个遍历。
- 在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。缺点
- 由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
使用场景
- 访问一个聚合对象的内容而无需暴露它的内部表示
- 支持对聚合对象的多种遍历
- 为遍历不同的聚合结构提供一个统一的接口
java中常用的容器类如ArrayList,HashMap等都采用了Iterator,具体细节可以看看java源码
迭代器接口
public interface Iterator {
Object next();
boolean hasNext();
boolean remove();
}
具体迭代器
public class ConcreteIterator implements Iterator {
private Vector<Object> vector;
private int cursor = 0;
public ConcreteIterator(Vector<Object> _vector) {
vector = _vector;
}
/**
* 获取下一个元素,没有则返回空
*
* @return 下一个元素
*/
@Override
public Object next() {
Object result = null;
if (hasNext()) {
result = vector.get(cursor++);
}
return result;
}
@Override
public boolean hasNext() {
return cursor != vector.size();
}
@Override
public boolean remove() {
vector.remove(cursor);
return true;
}
}
抽象容器
public interface Agregate {
Iterator iterator();
void add(Object o);
void remove(Object o);
}
具体容器
public class ConcreteAgregate implements Agregate {
private Vector<Object> vector = new Vector<>();
@Override
public Iterator iterator() {
return new ConcreteIterator(this.vector);
}
@Override
public void add(Object o) {
this.vector.add(o);
}
@Override
public void remove(Object o) {
this.vector.remove(o);
}
}
场景类
public class Client {
public static void main(String[] args) {
//新建容器类
Agregate agr = new ConcreteAgregate();
agr.add("Bobby");
agr.add("Gu");
agr.add("gbj");
//获得迭代器
Iterator iterator = agr.iterator();
//执行遍历
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
运行结果
Bobby
Gu
gbj
来看看ArrayList迭代器源码
private class Itr implements Iterator<E> {
int cursor;
int lastRet = -1;
int expectedModCount;
Itr() {
this.expectedModCount = ArrayList.this.modCount;
}
public boolean hasNext() {
return this.cursor != ArrayList.this.size;
}
public E next() {
this.checkForComodification();
int var1 = this.cursor;
if (var1 >= ArrayList.this.size) {
throw new NoSuchElementException();
} else {
Object[] var2 = ArrayList.this.elementData;
if (var1 >= var2.length) {
throw new ConcurrentModificationException();
} else {
this.cursor = var1 + 1;
return var2[this.lastRet = var1];
}
}
}
public void remove() {
if (this.lastRet < 0) {
throw new IllegalStateException();
} else {
this.checkForComodification();
try {
ArrayList.this.remove(this.lastRet);
this.cursor = this.lastRet;
this.lastRet = -1;
this.expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException var2) {
throw new ConcurrentModificationException();
}
}
}
public void forEachRemaining(Consumer<? super E> var1) {
Objects.requireNonNull(var1);
int var2 = ArrayList.this.size;
int var3 = this.cursor;
if (var3 < var2) {
Object[] var4 = ArrayList.this.elementData;
if (var3 >= var4.length) {
throw new ConcurrentModificationException();
} else {
while(var3 != var2 && ArrayList.this.modCount == this.expectedModCount) {
var1.accept(var4[var3++]);
}
this.cursor = var3;
this.lastRet = var3 - 1;
this.checkForComodification();
}
}
}
final void checkForComodification() {
if (ArrayList.this.modCount != this.expectedModCount) {
throw new ConcurrentModificationException();
}
}
}