🔥「炎码工坊」技术弹药已装填!
点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】
引言:从"统一访问"到"设计之美"
在Java集合框架的星空中,迭代器(Iterator)如同一颗低调却璀璨的星辰。它让开发者无需理解ArrayList
的数组结构、LinkedList
的链表特性,甚至无需关心HashMap
的红黑树实现,即可用同一套API遍历所有集合。这种"魔法"背后,暗藏着GoF设计模式的经典演绎与Java设计者的精妙巧思。
一、迭代器模式:解耦容器与算法的终极方案
1.1 经典设计模式的完美落地
迭代器模式通过四重角色构建了优雅的解耦架构:
- 抽象聚合(Aggregate):
Collection
接口定义iterator()
方法 - 具体聚合:
ArrayList
实现iterator()
返回Itr
实例 - 抽象迭代器:
Iterator<E>
定义hasNext()
,next()
,remove()
- 具体迭代器:
HashMap.HashIterator
等实现特定结构遍历逻辑
示例:自定义频道迭代器
// Channel POJO定义
public class Channel {
private int number;
private ChannelTypeEnum type;
// 构造方法/getter/setter省略
}
// 抽象迭代器
public interface ChannelIterator {
boolean hasNext();
Channel next();
}
// 具体迭代器实现
public class ChannelTypeIterator implements ChannelIterator {
private List<Channel> channels;
private int position = 0;
private ChannelTypeEnum type;
public ChannelTypeIterator(List<Channel> channels, ChannelTypeEnum type) {
this.channels = channels;
this.type = type;
}
@Override
public boolean hasNext() {
while (position < channels.size()) {
if (channels.get(position).getType() == type) return true;
position++;
}
return false;
}
@Override
public Channel next() {
return channels.get(position++);
}
}
二、JDK源码探秘:迭代器的实现原理
2.1 ArrayList的迭代器实现
private class Itr implements Iterator<E> {
int cursor; // 下一个元素索引
int lastRet = -1; // 最后返回的元素索引
int expectedModCount = modCount; // 结构性修改计数器
public E next() {
checkForComodification(); // 并发修改检测
int i = cursor;
Object[] elementData = ArrayList.this.elementData;
cursor = i + 1;
return (E) elementData[lastRet = i];
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
2.2 HashMap的迭代秘密
abstract class HashIterator {
Node<K,V> next; // 下一个节点
Node<K,V> current; // 当前节点
int index; // 当前桶索引
HashIterator() {
expectedModCount = modCount;
Node<K,V>[] t = table;
currentIndex = 0;
// 寻找第一个非空桶
while (index < t.length && (next = t[index++]) == null);
}
public final boolean hasNext() {
return next != null;
}
}
三、进阶实践:超越基本用法的技巧
3.1 安全删除的黄金法则
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()) {
String item = iterator.next();
if(shouldRemove(item)) {
iterator.remove(); // 正确使用方式
}
}
// 错误示范:list.remove(item)会抛出ConcurrentModificationException
3.2 Spliterator并行迭代
Java 8引入的Spliterator
支持高效并行处理:
Spliterator<String> spliterator = list.spliterator();
spliterator.forEachRemaining(System.out::println);
3.3 自定义过滤器迭代器
public class FilterIterator<T> implements Iterator<T> {
private Iterator<T> delegate;
private Predicate<T> predicate;
public FilterIterator(Iterator<T> delegate, Predicate<T> predicate) {
this.delegate = delegate;
this.predicate = predicate;
}
@Override
public boolean hasNext() {
while(delegate.hasNext()) {
T candidate = delegate.next();
if(predicate.test(candidate)) {
this.next = candidate;
return true;
}
}
return false;
}
}
四、设计哲学:为什么选择迭代器模式?
4.1 三大设计原则的完美诠释
- 开闭原则:新增
DescendingIterator
无需修改List
接口 - 单一职责:
ArrayList
专注数据存储,Iterator
负责遍历算法 - 里氏替换:
ListIterator
扩展功能时保持原有契约
4.2 性能权衡的艺术
场景 | 迭代器效率 | 直接访问效率 | 差距来源 |
ArrayList随机访问 | O(n) | O(n) | 几乎无差异 |
LinkedList顺序遍历 | O(n) | O(n²) | 链表指针跳转 |
HashMap元素遍历 | O(n) | 不可直接遍历 | 结构复杂性 |
五、现代Java的迭代演进
5.1 Stream API的迭代革命
list.stream()
.filter(s -> s.startsWith("A"))
.map(String::toUpperCase)
.forEach(System.out::println);
5.2 迭代器与响应式编程
Project Reactor中的Flux
延续了迭代器思想:
Flux.fromIterable(list)
.filterWhen(this::checkPermission)
.subscribe(this::processItem);
结语:迭代器模式的永恒价值
从JDK 1.2到现代Java,迭代器模式始终闪耀着设计智慧的光芒。它不仅是遍历集合的工具,更是理解Java集合框架设计思想的钥匙。掌握迭代器的本质,意味着在面对复杂数据结构时,既能"知其然"地高效开发,又能"知其所以然"地架构设计。
延伸思考:当函数式编程遇上迭代器模式,是否预示着下一次设计模式的进化?欢迎在评论区探讨Java迭代器的未来演进方向。
🚧 您已阅读完全文99%!缺少1%的关键操作:
加入「炎码燃料仓」🚀 获得:
√ 开源工具红黑榜
√ 项目落地避坑指南
√ 每周BUG修复进度+1%彩蛋
(温馨提示:本工坊不打灰工,只烧脑洞🔥)