新专题:设计模式,我会在博客(http://www.hollischuang.com)及微信公众号(hollischuang)同步更新,欢迎共同学习。
上一篇介绍了迭代器模式,而且我们也提到,迭代器模式在JAVA的很多集合类中应用广泛,本文就来看看JAVA源码中是如何使用迭代器模式的。
以下这段代码是JAVA中比较常见的,使用迭代器来遍历List:
List<String> list = new ArrayList<>();
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
在上一篇文章中,我们介绍过迭代器模式中包括的几个角色:
Iterator 抽象迭代器
ConcreteIterator 具体迭代器
Aggregate 抽象容器
Concrete Aggregate 具体容器
我们看看ArrayList
在使用迭代器的时候是否也包含这些角色。
首先,具体的容器就不用说了,ArrayList
类本身就是这个具体的容器类。我们看得到,ArrayList
中包含一个iterator
方法,该方法用来返回一个具体的迭代器。
在介绍这个具体的迭代器的实现之前,我们先来找找这个迭代器模式的实现中是否包含抽象迭代器和抽象容器。
抽象容器比较好找,只要我们找到这个iterator
方法在哪个接口中定义的就可以了。这里直接给出答案:java.util.Iterable
。
抽象迭代器就是java.util.Iterator
当我们在使用JAVA开发的时候,想使用迭代器模式的话,只要让我们自己定义的容器类实现java.util.Iterable
并实现其中的iterator方法使其返回一个java.util.Iterator
的实现类就可以了。
我们接下来看一下ArrayList
中的iterator
方法是如何实现的,直接贴源码(jdk1.8.0_73):
public Iterator<E> iterator() {
return new Itr();
}
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;
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();
}
}
上面的代码比较简单,应该都可以看得懂,这里的实现很容易理解,就是iterator
方法中new
了一个Iterator
的实现类并反回了。Itr
是一个内部类,他实现了Iterator
接口并实现了其中的方法。
至此,看完了JAVA中ArrayList
对迭代器模式的实现。通过迭代器,可以不必关心其内部实现方式。
当我们在使用JAVA开发的时候,想使用迭代器模式的话,只要让我们自己定义的容器类实现java.util.Iterable
并实现其中的iterator方法使其返回一个java.util.Iterator
的实现类就可以了。