一、介绍
迭代器模式提供一种顺序访问集合对象元素的方法,而不需要暴露集合对象的内部表示。迭代器模式可以让不同的集合对象使用统一的迭代接口,从而避免了对集合对象的复杂操作。
比如你要清点家里的物品,不同的房间里有不同的物品,但是你只需要一个标准的清点流程(迭代器),就可以清点不同房间里的物品,而不用关心每个房间的具体物品安排。
二、实际项目中的应用
需求:在一个图书管理系统中,需要遍历不同类型的图书集合,如小说、科技、历史等,并能够统一地展示图书信息。
实现:
- 定义图书接口
- 实现具体的图书类
- 定义图书迭代器接口
- 实现具体的图书迭代器
- 使用迭代器遍历图书
// 1. 定义图书接口
interface Book {
String getBookName();
Iterator<String> getIterator();
}
// 2. 实现具体的图书类
class FictionBook implements Book {
private List<String> chapters = new ArrayList<>();
public FictionBook() {
chapters.add("第一章");
chapters.add("第二章");
chapters.add("第三章");
}
@Override
public String getBookName() {
return "小说书籍";
}
@Override
public Iterator<String> getIterator() {
return new FictionBookIterator(this);
}
private class FictionBookIterator implements Iterator<String> {
private FictionBook book;
private int index = 0;
public FictionBookIterator(FictionBook book) {
this.book = book;
}
@Override
public boolean hasNext() {
return index < book.chapters.size();
}
@Override
public String next() {
if (hasNext()) {
return book.chapters.get(index++);
}
throw new NoSuchElementException();
}
}
}
class TechBook implements Book {
private List<String> chapters = new ArrayList<>();
public TechBook() {
chapters.add("第一章");
chapters.add("第二章");
chapters.add("第三章");
}
@Override
public String getBookName() {
return "科技书籍";
}
@Override
public Iterator<String> getIterator() {
return new TechBookIterator(this);
}
private class TechBookIterator implements Iterator<String> {
private TechBook book;
private int index = 0;
public TechBookIterator(TechBook book) {
this.book = book;
}
@Override
public boolean hasNext() {
return index < book.chapters.size();
}
@Override
public String next() {
if (hasNext()) {
return book.chapters.get(index++);
}
throw new NoSuchElementException();
}
}
}
// 3. 定义图书迭代器接口 (已包含在上面的代码中)
// 4. 实现具体的图书迭代器 (已包含在上面的代码中)
// 5. 使用迭代器遍历图书
public class BookClient {
public static void main(String[] args) {
Book fictionBook = new FictionBook();
Book techBook = new TechBook();
System.out.println("图书名称: " + fictionBook.getBookName());
printBook(fictionBook.getIterator());
System.out.println("\n图书名称: " + techBook.getBookName());
printBook(techBook.getIterator());
}
private static void printBook(Iterator<String> iterator) {
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
三、Java源码中的迭代器模式
java.util.Iterator
接口是Java集合框架中迭代器模式的典型应用。它定义了迭代器需要实现的方法,如hasNext()
和next()
。
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
// 其他方法...
}
Java集合框架中的ArrayList
、LinkedList
、HashSet
等集合类都实现了Iterable
接口,它提供了iterator()
方法来获取迭代器。
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
// ...
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
// 实现hasNext()和next()方法
}
}
四、总结优缺点以及使用经验
优点:
- 支持不同的遍历方式,迭代器模式简化了遍历操作
- 迭代器模式和集合类相分离,有利于增加新的集合类
- 迭代器模式适用于访问集合元素的多态性
缺点:
- 对于非常大的数据集合,使用迭代器遍历效率较低
- 迭代器模式会产生多个迭代器对象
使用经验:
- 使用迭代器模式可以有效地将集合对象的遍历操作与集合对象本身解耦
- 当需要遍历不同类型的集合对象时,可以考虑使用迭代器模式
- 在并发环境下,要注意迭代器的安全性问题
- 如果集合对象已经提供了迭代器,可以直接使用,无需自己实现迭代器
- 迭代器模式常用于框架和库的设计中,如Java集合框架