定义
提供一种方法,顺序访问一个集合对象中的各个元素,而又不暴露该对象的内部表示。
适用场景
- 访问一个集合对象的内容而无需暴露他的内部表示
- 为遍历不同的集合结构提供了一个统一的接口。
优点
- 分离了集合对象的遍历行为
缺点
- 类的个数成对增加
开源实现
由于迭代器模式一般都会使用 java.util
包里的 Iterator
实现或者是谷歌的guava中的实现。因此自己写demo例子显得有些多余。我们直接可以根据JDK中的源码来探索迭代器模式的奥秘。
首先迭代器模式需要一个迭代器接口,JDK中的public interface Iterator<E>
就是 其迭代器的接口。
public interface Iterator<E> {
//是否有下一个元素
boolean hasNext();
//获取下一个元素
E next();
//删除当前元素
default void remove() {
throw new UnsupportedOperationException("remove");
}
//JAVA 1.8版本新增的实现 对每个元素执行某个操作
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
看了接口,我们就需要一个实现类来仔细看一下,我们选择ArrayList
为参考 我们打开ArrayList
源码。发现其中有一个内部实现类。我们来看一下其具体实现。
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
//省略部分代码
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();
}
}
//省略部分代码
}
这里的具体实现相信大家都可以看清楚,就不多做赘述了。
小结
对于迭代器模式在我们迭代 集合的时候比如List
,Set
等用的比较多,而自己去写一个迭代器不但代码复杂,而且重复造轮子也太严重了。
网友评论