迭代器模式
欢迎来到我的 ChatGPT 中转站,极具性价比,为付费不方便的朋友提供便利,有需求的可以添加左侧 QQ 二维码,另外,邀请新用户能获取余额哦!最后说一句,那啥:请自觉遵守《生成式人工智能服务管理暂行办法》。
# 简介
迭代器模式(Iterator Pattern)是常用的设计模式,属于行为型模式。
如果我们的集合元素是用不同的方式实现的,有数组,还有 java 的集合类,或者还有其他方式,当客户端要遍历这些集合元素的时候就要使用多种遍历方式,而且还会暴露元素的内部结构,可以考虑使用迭代器模式解决。
迭代器模式,提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构。
Iterator
接口定义了迭代器的基本行为,包括hasNext
方法用于检查是否有下一个元素,以及next
方法用于获取下一个元素。Aggregate
接口定义了聚合的基本行为,其中createIterator
方法用于创建一个迭代器。ConcreteIterator
类是迭代器的具体实现,包含了一个索引和对集合的引用。它实现了Iterator
接口的方法。ConcreteAggregate
类是聚合的具体实现,包含了一个对象数组用于存储元素。它实现了Aggregate
接口的方法,包括createIterator
方法,该方法返回一个与该聚合兼容的迭代器。
# 迭代器模式
# 代码示例
/**
* 系
*/
@ToString
@AllArgsConstructor
@Data
public class Department {
private String name;// 名称
private String desc;// 简介
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
/**
* 学院,Aggregate
*/
public interface College {
// 获取名称
String getName();
// 创建迭代器
Iterator<Department> createIterator();
// 新增加一个院系
void addDepartment(Department department);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 信息学院迭代器
*/
public class InfoColleageIterator implements Iterator<Department> {
private final List<Department> departments;
private int index = 0;
public InfoColleageIterator(List<Department> departments) {
this.departments = departments;
}
@Override
public boolean hasNext() {
return !departments.isEmpty() && index + 1 <= departments.size();
}
@Override
public Department next() {
Department department = departments.get(index);
index++;
return department;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 计算机学院迭代器
*/
public class ComputerCollegeIterator implements Iterator<Department> {
private final Department[] departments;
private int index = 0;
public ComputerCollegeIterator(Department[] departments) {
this.departments = departments;
}
@Override
public boolean hasNext() {
return departments.length > 0 && departments[index] != null;
}
@Override
public Department next() {
Department department = departments[index];
index++;
return department;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 计算机学院,ConcreteAggregate
*/
public class ComputerCollege implements College {
// 维护一个院系
private final Department[] departments;
// 维护一个下标索引
private int index = 0;
public ComputerCollege() {
departments = new Department[5];
addDepartment(new Department("Java专业", " Java专业 "));
addDepartment(new Department("PHP专业", " PHP专业 "));
addDepartment(new Department("大数据专业", " 大数据专业 "));
}
@Override
public String getName() {
return "计算机学院";
}
@Override
public Iterator<Department> createIterator() {
return new ComputerCollegeIterator(departments);
}
@Override
public void addDepartment(Department department) {
departments[index] = department;
index++;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* 信息工程学院,ConcreteAggregate
*/
public class InfoCollege implements College {
// 维护一个院系
private final List<Department> departments;
public InfoCollege() {
departments = new ArrayList<>();
addDepartment(new Department("信息安全专业", " 信息安全专业 "));
addDepartment(new Department("网络安全专业", " 网络安全专业 "));
addDepartment(new Department("服务器安全专业", " 服务器安全专业 "));
}
@Override
public String getName() {
return "信息工程学院";
}
@Override
public Iterator<Department> createIterator() {
return new InfoColleageIterator(departments);
}
@Override
public void addDepartment(Department department) {
departments.add(department);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* 打印学院和系
*/
public class OutPutImpl {
private List<College> colleges;
public OutPutImpl(List<College> colleges) {
this.colleges = colleges;
}
// 遍历所有学院和系
public void printCollege() {
Iterator<College> iterator = colleges.iterator();
while (iterator.hasNext()) {
College college = iterator.next();
System.out.println("=== " + college.getName() + "=====");
Iterator<Department> departmentIterator = college.createIterator();
printDepartment(departmentIterator);
}
}
//打印系
private void printDepartment(Iterator<Department> iterator) {
while (iterator.hasNext()) {
Department d = iterator.next();
System.out.println(d.getName());
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Client {
public static void main(String[] args) {
List<College> collegeList = new ArrayList<College>();
ComputerCollege computerCollege = new ComputerCollege();
InfoCollege infoCollege = new InfoCollege();
collegeList.add(computerCollege);
collegeList.add(infoCollege);
OutPutImpl outPut = new OutPutImpl(collegeList);
outPut.printCollege();
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# ArrayList 中迭代器的使用
// ArrayList 内部维护了一个迭代器实现类, 重写了3个方法。
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;
Itr() {}
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();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 说明
- 优点
- 提供一个统一的方法遍历对象,客户不用再考虑聚合的类型,使用一种方法就可以遍历对象了。
- 隐藏了聚合的内部结构,客户端要遍历聚合的时候只能取到迭代器,而不会知道聚 合的具体组成。
- 提供了一种设计思想,就是一个类应该只有一个引起变化的原因(叫做单一责任原则)。在聚合类中,我们把迭代器分开,就是要把管理对象集合和遍历对象集 合的责任分开,这样一来集合改变的话,只影响到聚合对象。而如果遍历方式改变的话,只影响到了迭代器。
- 当要展示一组相似对象,或者遍历一组相同对象时使用,适合使用迭代器模式。
- 缺点
- 每个聚合对象都要一个迭代器,会生成多个迭代器不好管理类。
上次更新: 2025/04/12, 05:37:39