IBookList list = ...;
BookListIterator it = list.iterator();
while(it.hasNext()){
Book book = it.next();
...
}
我们举例来说明Iterator模式到底好在哪。
比如有一个Book类,一个管理Book的容器类BookList:
public class Book {
...
}
public class BookList {
//保存Book对象数据
private List bookList = new ArrayList();
//添加Book对象至BookList容器
public void addBook(Book book) {
...
}
//从BookList容器删除Book对象
public void deleteBook(Book book) {
...
}
//其他方法
...
}
方法1,由容器自己实现顺序遍历。直接在BookList里添加顺序遍历方法:
public class BookList {
private int index;
...
//得到当前Book
public Book getCurrentBook() {
...
Book book = (Book)bookList.get(index);
...
return book;
}
//是否存在下一个Book
public boolean hasNext() {
...
}
}
使用时,可能的使用方法是:
BookList bookList = ...;
...
while (bookList.hasNext()) {
Book book = bookList.getCurrentBook();
//对Book加以处理(略)
...
}
方法2,让调用者自己实现遍历。直接暴露BookList数据细节给外部,比如:
public class BookList {
...
public List <Book> getBookList() {
...
return bookList;
}
}
可能的使用方法为:
BookList bookList = ...;
List <Book>bookDataList = bookList.getBookList();
...
for (int i=0; bookDataList != null && i<bookDataList.size(); i++) {
Book book = bookDataList.get(i);
//对Book加以处理(略)
...
}
以上方法1与方法2都可以实现对BookList所包含的Book对象进行遍历,这样有问题呢?
确实使用上没有任何问题。
但实现方法1中,
1,容器类BookList承担了太多功能:一方面需要提供添加删除等BookList本身应有的功能;一方面还需要提供遍历访问功能。
2,往往容器在实现遍历的过程中,需要保存遍历状态,当跟元素的添加删除等功能夹杂在一起,很容易引起混乱和程序运行错误等。
在实现方法2中,
容器本身未实现任何遍历方法,把这个遍历的任务交给了调用者,这样一来,暴露了容器本身的实现细节,如果一旦容器内部的数据接口发生变化,比如由于某种原 因,BookList的List bookList用Map bookList来实现,这样,所有调用方的程序不得不随着BookList的修改而修改。
Iterator模式很好地解决了以上问题。
我们先从JDK中的Collection Framework对Iterator模式的实现方法来说明Iterator模式。
Java Collection Framework对迭代模式的经典实现
1、Iterable.java
public interface Iterable<T> {
Iterator<T> iterator();
}
2、迭代接口:Iterator接口,定义了遍历接口:
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
3,容器接口:Collection接口,定义了iterator()方法,把遍历委让给Iterator的实现类。
public interface Collection<E> extends Iterable<E> {
......
Iterator<E> iterator();
......
}
4、容器接口Collection的实现类与迭代接口Iterator的实现类:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
protected AbstractList() {
}
......
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
int lastRet = -1;
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size();
}
public E next() {
checkForComodification();
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
......
}
以上说明了Java Collection Framework里的对Iterator模式的基本实现方法。
这也是Iterator模式一种经典的实现方案。
迭代器接口Iterator :该接口必须定义实现迭代功能的最小定义方法集比如提供hasNext()和next()方法。
迭代器实现类 :迭代器接口Iterator的实现类。可以根据具体情况加以实现。
容器接口 :定义基本功能以及提供类似Iterator iterator()的方法。
容器实现类 :容器接口的实现类。必须实现Iterator iterator()方法。
Iterator模式的类图:
应用我们的上面介绍的例子,我们需要定义以下几个接口与类:
public class public interface IBookList {
public BookListIterator iterator();
}
BookListImpl implements IBookList {
public BookListIterator iterator() {
return new BookListIteratorImpl(this);
}
}
public interface BookListIterator {
public boolean hasNext();
public Book next();
}
public class BookListIteratorImpl implements BookListIterator {
...(具体实现过程略)
}
对容器的遍历方法例:
IBookList list = ...;
BookListIterator it = list.iterator();
while(it.hasNext()){
Book book = it.next();
...
}
2,隐藏容器的实现细节。
3,为容器或其子容器提供了一个统一接口,一方面方便调用;另一方面使得调用者不必关注迭代器的实现细节。
4,可以为容器或其子容器实现不同的迭代方法或多个迭代方法。
转载于:https://blog.51cto.com/sky2012/1318034