前言
龙年开工大吉!
迭代器模式,之前在责任链模式中出现过,结合责任链模式完成动态的模块加载。
迭代,就是遍历集合对象,其实也就是for循环,正常我们也很少使用迭代器模式,因为框架都帮我们封装好了。
那迭代器模式、与 for 循环遍历、foreach 遍历有何区别呢?
今天我们就来浅学迭代器模式。
一、概念
1.1 概念
来看相关概念。
迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。
回到前面的问题,遍历集合对象的三种方式:
For 循环相对 Iterator 代码更加简洁,一般情况下我们用的也最多,而foreach 底层的实现就是迭代器模式。
那为什么还要用迭代器来遍历容器呢?
原因有如下几点:
-
1、对于线性结构的遍历,for循环完全足够了,但是在图、树的复杂遍历下,有深度优先、广度优先、前序、后序等多种遍历算法,这些遍历算法不能由我们自己来实现,也不能放到容器中不然会导致代码复杂性;解决的方式就是将遍历操作拆分到迭代器类中,例如对图的遍历,分别创建深度迭代器、广度迭代器两个迭代类;
-
2、新增一种遍历算法,我们创建一个迭代器类,实现开闭原则。
迭代器模式的使用就是遍历和解耦容器代码。
1.2 结构
迭代器模式主要有如下四个角色:
-
Iterator(抽象迭代器):定义访问和遍历容器元素的接口,通常有 hasNext、next 等方法;
-
Concretelterator(具体迭代器):实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历;
-
Aggregate(抽象聚合):定义新增、修改、删除聚合元素以及创建迭代器对象的接口;
-
ConcreteAggregate(具体聚合):实现抽象聚合,返回一个具体的迭代器实例。
我们可以来分析下聚合和迭代器的概念。
-
迭代器:
- 就是控制方,可以控制切换聚合元素的控制器。
- 将遍历数据的行为从聚合对象中分离出来,封装到迭代器对象中
-
聚合对象:
- 聚合对象存储具体元素对象
1.3 优缺点
优点:
- 支持多种遍历方式,只需要实现不同的迭代器,即可实现聚合对象的遍历算法;
- 降低了聚合对象和迭代器之间的耦合度,使得聚合对象的内部结构可以随意变化而不影响遍历操作。
- 引入抽象层,符合开闭原则
缺点:
-
新增类的个数,提高系统复杂度
-
在某些情况下,可能会导致性能问题,因为迭代器模式需要额外的对象来维护遍历状态,可能会增加内存消耗和运行时开销。
-
对于简单的遍历操作,使用迭代器模式可能显得过于繁琐,不利于代码的简洁性。
二、案例
迭代器案例,就是对象的遍历。
java
import java.util.ArrayList;
import java.util.List;
// 创建具体的元素类
class Student {
private String name;
private String age;
public Student(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public String getAge() {
return age;
}
}
// 创建迭代器接口
interface Iterator {
boolean hasNext();
Object next();
}
// 创建具体的迭代器类
class StudentIterator implements Iterator {
private List<Student> students;
private int index;
public StudentIterator(List<Student> students) {
this.students = students;
this.index = 0;
}
@Override
public boolean hasNext() {
return index < students.size();
}
@Override
public Object next() {
Student student = students.get(index);
index++;
return student;
}
}
// 创建抽象聚合类
interface Aggregate {
Iterator createIterator();
}
// 创建具体的聚合类
class StudentCollection implements Aggregate {
private List<Student> students;
public StudentCollection() {
students = new ArrayList<>();
}
public void addStudent(Student student) {
students.add(student);
}
@Override
public Iterator createIterator() {
return new StudentIterator(students);
}
}
// 主程序
public class Main {
public static void main(String[] args) {
Student student1 = new Student("大毛", "20");
Student student2 = new Student("二毛", "22");
StudentCollection studentCollection = new StudentCollection();
studentCollection.addStudent(student1);
studentCollection.addStudent(student2);
Iterator iterator = studentCollection.createIterator();
while (iterator.hasNext()) {
Student student = (Student) iterator.next();
System.out.println("Name: " + student.getName() + ", Age: " + student.getAge());
}
}
}
三、小结
迭代器模式适合以下场景:
- 当你希望访问一个聚合对象的内容,但又不想暴露其内部结构时,可以使用迭代器模式。
- 当你需要对不同类型的聚合对象进行统一的遍历操作时,可以使用迭代器模式。
- 当你希望提供多种遍历方式(正向遍历、逆向遍历等)时,可以使用迭代器模式。
- 当你希望分离遍历算法和集合对象时,可以使用迭代器模式。