迭代器模式(Iterator Pattern)
迭代器模式(Iterator Pattern)
迭代器模式是一种行为型设计模式,它提供一种方法顺序访问一个集合中的各个元素,而又不暴露集合的内部表示。迭代器模式通过将遍历集合的责任交给迭代器对象,使得客户端可以透明地访问集合中的元素,而无需关心集合的底层实现。
模式结构
- 迭代器接口(Iterator)
定义遍历集合所需的操作,通常包含hasNext()
和next()
方法。 - 具体迭代器(Concrete Iterator)
实现迭代器接口,负责遍历集合中的元素。它通常持有一个集合的引用,并跟踪当前的遍历位置。 - 集合接口(Collection)
定义获取迭代器的方法,通常包含一个iterator()
方法。 - 具体集合(Concrete Collection)
实现集合接口,负责存储和管理元素,并提供获取迭代器的方法。 - 客户端(Client)
通过迭代器接口遍历集合中的元素,而无需关心集合的内部结构。
代码示例
1. 迭代器接口(Iterator)
// 迭代器接口:定义遍历集合所需的操作
interface CourseIterator {
Boolean hasNext();
Course next();
}
2. 具体迭代器(Concrete Iterator)
// 具体迭代器:实现迭代器接口
class CourserIteratorImpl implements CourseIterator {
private final MajorType majorType;
private final List<Course> courses;
private int position;
public CourserIteratorImpl(MajorType majorType, List<Course> courses) {
this.majorType = majorType;
this.courses = courses;
}
@Override
public Boolean hasNext() {
while (position < courses.size()) {
Course course = courses.get(position);
if (course.getMajorType().equals(majorType) || majorType.equals(MajorType.ALL)) {
return true;
} else {
position++;
}
}
return false;
}
@Override
public Course next() {
Course course = courses.get(position);
position++;
return course;
}
}
3. 集合接口(Collection)
// 集合接口:定义获取迭代器的方法
interface CourseCollection {
void add(Course course);
void remove(Course course);
CourseIterator iterator(MajorType majorType);
}
4. 具体集合(Concrete Collection)
// 具体集合:实现集合接口
class CourseCollectionImpl implements CourseCollection {
private final List<Course> courses;
public CourseCollectionImpl() {
courses = new ArrayList<>();
}
@Override
public void add(Course course) {
courses.add(course);
}
@Override
public void remove(Course course) {
courses.remove(course);
}
@Override
public CourseIterator iterator(MajorType majorType) {
return new CourserIteratorImpl(majorType, courses);
}
}
5.调用示例
public class IteratorPattern {
public static void main(String[] args) {
CourseCollection courses = initCollection();
// 遍历所有课程
CourseIterator all = courses.iterator(MajorType.ALL);
while (all.hasNext()) {
Course course = all.next();
System.out.println(course);
}
System.out.println("\n<----------------------------->\n");
// 遍历计算机科学课程
CourseIterator cs = courses.iterator(MajorType.COMPUTER_SCIENCES);
while (cs.hasNext()) {
Course course = cs.next();
System.out.println(course);
}
}
private static CourseCollection initCollection() {
CourseCollection courses = new CourseCollectionImpl();
courses.add(new Course("计算机网络", MajorType.COMPUTER_SCIENCES));
courses.add(new Course("计算机操作系统", MajorType.COMPUTER_SCIENCES));
courses.add(new Course("计算机组成原理", MajorType.COMPUTER_SCIENCES));
courses.add(new Course("数据结构与算法", MajorType.COMPUTER_SCIENCES));
courses.add(new Course("生物化学", MajorType.BIOLOGY_SCIENCES));
courses.add(new Course("高等数学", MajorType.MATH));
courses.add(new Course("宏观经济学", MajorType.FINANCE));
courses.add(new Course("中国通史", MajorType.HISTORY));
return courses;
}
}
输出结果
Course{name='计算机网络', majorType=计算机科学与技术}
Course{name='计算机操作系统', majorType=计算机科学与技术}
Course{name='计算机组成原理', majorType=计算机科学与技术}
Course{name='数据结构与算法', majorType=计算机科学与技术}
Course{name='生物化学', majorType=生物科学}
Course{name='高等数学', majorType=数学}
Course{name='宏观经济学', majorType=金融}
Course{name='中国通史', majorType=历史}
<----------------------------->
Course{name='计算机网络', majorType=计算机科学与技术}
Course{name='计算机操作系统', majorType=计算机科学与技术}
Course{name='计算机组成原理', majorType=计算机科学与技术}
Course{name='数据结构与算法', majorType=计算机科学与技术}
应用场景
- 隐藏集合的内部结构
当集合的底层数据结构较为复杂时,可以使用迭代器模式隐藏其内部结构,使得客户端可以透明地访问集合中的元素。 - 多种遍历方式
当需要为集合提供多种遍历方式时,可以使用迭代器模式。不同的迭代器可以实现不同的遍历逻辑。 - 简化遍历代码
当业务逻辑中存在大量的遍历代码时,可以使用迭代器模式将遍历代码抽离到迭代器中,简化原有方法的职责。
在Java中的应用
java.util.Iterator
Java 集合框架中的Iterator
接口就是迭代器模式的典型应用。ArrayList
、HashSet
等集合类都提供了iterator()
方法来获取迭代器。java.util.Scanner
Scanner
类可以看作是一个迭代器,它允许逐行读取输入流中的数据。java.util.Enumeration
Enumeration
是 Java 早期提供的迭代器接口,用于遍历集合中的元素。
优缺点
优点
- 简化集合的遍历
迭代器模式将遍历集合的责任交给迭代器对象,使得客户端可以透明地访问集合中的元素。 - 支持多种遍历方式
迭代器模式可以为集合提供多种遍历方式,不同的迭代器可以实现不同的遍历逻辑。 - 符合单一职责原则
迭代器模式将集合的遍历行为分离到迭代器中,符合单一职责原则。
缺点
- 增加代码复杂性
迭代器模式引入了额外的类和接口,增加了代码的复杂性。 - 性能开销
对于某些特殊的集合,使用迭代器进行遍历可能会引入额外的性能开销。
总结
迭代器模式通过将遍历集合的责任交给迭代器对象,使得客户端可以透明地访问集合中的元素,而无需关心集合的内部结构。它适用于需要隐藏集合内部结构、提供多种遍历方式或简化遍历代码的场景。尽管它可能会增加代码的复杂性,但其优点在于提高了代码的灵活性和可维护性。在Java中,迭代器模式广泛应用于集合框架和输入流处理等场景。