网站首页 > java教程 正文
一句话总结:迭代器模式(Iterator Pattern)让你不暴露集合内部结构,就能遍历集合元素。它是Java集合框架的基石,也是解耦遍历与集合的关键设计模式。
一、先看痛点:为什么需要迭代器?
假设有一个「待办任务列表」用ArrayList和LinkedList两种方式实现:
// ArrayList实现
List<String> arrayTaskList = new ArrayList<>();
arrayTaskList.add("写周报");
arrayTaskList.add("修复Bug");
// LinkedList实现
List<String> linkedTaskList = new LinkedList<>();
linkedTaskList.add("设计新功能");
linkedTaskList.add("代码Review");
问题:
- 如果遍历时分别调arrayTaskList.get(i)和linkedTaskList.get(i),性能天差地别(链表随机访问O(n))。
- 客户端必须知道集合具体类型,耦合度高。
- 新增集合类型(如树结构)需重写遍历逻辑。
二、迭代器模式解决方案
核心思想:将遍历行为抽离成独立对象。
1. UML结构
┌─────────────┐
│ Iterator │
├─────────────┤
│ hasNext() │
│ next() │
└─────────────┘
▲
│
┌──────────────────────┼──────────────────────┐
│ │ │
┌─────────────────┐ ┌───────────────────┐ ┌─────────────────┐
│ ArrayIterator │ │ LinkedListIterator│ │ TreeIterator │
├─────────────────┤ ├───────────────────┤ ├─────────────────┤
│ hasNext() │ │ hasNext() │ │ hasNext() │
│ next() │ │ next() │ │ next() │
└─────────────────┘ └───────────────────┘ └─────────────────┘
▲ ▲ ▲
│ │ │
┌─────────────────┐ ┌───────────────────┐ ┌─────────────────┐
│ ArrayList │ │ LinkedList │ │ Tree │
├─────────────────┤ ├───────────────────┤ ├─────────────────┤
│ iterator() │ │ iterator() │ │ iterator() │
└─────────────────┘ └───────────────────┘ └─────────────────┘
2. 代码实现
步骤1:定义迭代器接口
public interface Iterator<T> {
boolean hasNext();
T next();
}
步骤2:为不同集合实现迭代器
// ArrayList迭代器
public class ArrayIterator<T> implements Iterator<T> {
private final List<T> list;
private int index = 0;
public ArrayIterator(List<T> list) {
this.list = list;
}
@Override
public boolean hasNext() {
return index < list.size();
}
@Override
public T next() {
return list.get(index++);
}
}
// LinkedList迭代器(简化版)
public class LinkedListIterator<T> implements Iterator<T> {
private Node<T> current;
public LinkedListIterator(Node<T> head) {
this.current = head;
}
@Override
public boolean hasNext() {
return current != null;
}
@Override
public T next() {
T data = current.data;
current = current.next;
return data;
}
}
步骤3:在集合中返回迭代器
public class MyArrayList<T> {
private final List<T> list = new ArrayList<>();
public void add(T item) {
list.add(item);
}
public Iterator<T> iterator() {
return new ArrayIterator<>(list);
}
}
public class MyLinkedList<T> {
private static class Node<T> { /* 节点定义 */ }
private Node<T> head;
public void add(T data) { /* 添加节点 */ }
public Iterator<T> iterator() {
return new LinkedListIterator<>(head);
}
}
步骤4:客户端统一遍历
public class Client {
public static void main(String[] args) {
MyArrayList<String> tasks1 = new MyArrayList<>();
tasks1.add("写周报");
tasks1.add("修复Bug");
MyLinkedList<String> tasks2 = new MyLinkedList<>();
tasks2.add("设计新功能");
tasks2.add("代码Review");
// 统一遍历方式
traverse(tasks1.iterator());
traverse(tasks2.iterator());
}
private static void traverse(Iterator<String> iterator) {
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
三、适用场景(什么时候用?)
- 隐藏集合内部结构
- 客户端无需知道底层是数组、链表还是树。
- 统一遍历接口
- 对不同集合(如List、Set、Map)使用相同遍历逻辑。
- 支持并行遍历
- 多个迭代器可独立遍历同一集合(如游戏中的多个NPC寻路)。
- 简化客户端代码
- 避免在业务逻辑中混入for (int i=0; i<list.size(); i++)这类底层代码。
四、优缺点(为什么用?)
优点 | 缺点 |
解耦遍历与集合 | 增加额外类(小对象) |
支持多种遍历方式 | 简单集合用迭代器反而繁琐 |
符合开闭原则(新增集合无需改客户端) | |
隐藏集合实现细节 |
五、Java集合框架的经典应用
List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> it = list.iterator(); // 获取迭代器
Set<Integer> set = new HashSet<>(Set.of(1, 2, 3));
Iterator<Integer> setIt = set.iterator(); // 同样接口!
六、终极总结
- 用迭代器当你有多种集合需要遍历(数组、链表、树、图)。
- 用迭代器当你想隐藏集合复杂结构(如数据库查询结果集)。
- 不要用迭代器当集合极其简单(如单个数组直接for循环)。
设计模式本质:
隔离变化点 —— 将易变的集合结构与稳定的遍历行为分离。
猜你喜欢
- 2025-07-28 JDBC规范五-ResultSet详解(jdbc resultset fetchsize)
- 2025-07-28 Redis教程——数据类型(哈希、集合)
- 2025-07-28 Mybatis框架学习指南-第六节内容(常用的注解)
- 2025-07-28 用车按键指南:SET按键在汽车中的作用及操作流程详解!
- 2025-07-28 JSP request.setAttribute()详解及实例
- 2025-07-28 每天五分钟学习redis之SET命令(redis setns)
- 2025-07-28 python必须掌握的20个核心函数——set()函数
- 2025-07-28 redis set 详解(redis set 操作)
- 2025-07-28 Python学不会来打我(12)集合set详解:用法、场景与类型转换
- 2025-07-28 java中遍历map的几种方式(java遍历map的value)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)