扁平化遍历的核心是提供单层Iterator隐藏嵌套结构,通过栈式深度优先展开、按需计算实现内存高效;FlatIterator持迭代器栈委托执行,支持任意层级Iterable,类型安全由调用方保障。

理解扁平化遍历的核心需求
多层嵌套集合(如 List>
或更深层的 List>>
)直接用传统 for-each 遍历需多层循环。而“扁平化遍历”目标是暴露一个单层 Iterator
用组合方式实现 Iterator:核心思路
不继承 Iterator(它是个接口),而是让自定义类**持有并委托给一个内部迭代器**。该内部迭代器负责逐层探查、缓存当前有效子迭代器,并在 next() 时返回下一个真实元素。常用策略是维护一个“迭代器栈”或“迭代器队列”,优先处理最内层。
推荐采用**深度优先 + 栈式展开**(模拟递归展开顺序),逻辑清晰且易于控制:
- 初始化时,把顶层集合的迭代器压入栈
- hasNext():不断检查栈顶迭代器;若为空则弹出,继续检查上一层;若栈空则结束
- next():取栈顶迭代器的下一个元素;若该元素仍是集合,则将其迭代器压入栈,再重试取值
代码示例:FlatIterator 支持任意嵌套 Iterable
以下是一个泛型实现,支持任意嵌套层级的 Iterable(包括 List、Set、自定义容器等):
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
立即学习“Java免费学习笔记(深入)”;
public class FlatIterator<E> implements Iterator<E> {
private final Deque<Iterator<?>> stack = new ArrayDeque<>();
public FlatIterator(Iterable<?> root) {
if (root != null) stack.push(root.iterator());
}
@Override
public boolean hasNext() {
while (!stack.isEmpty()) {
Iterator<?> top = stack.peek();
if (!top.hasNext()) {
stack.pop(); // 当前层耗尽,退到上一层
continue;
}
Object next = top.next();
if (next instanceof Iterable<?>) {
stack.push(((Iterable<?>) next).iterator()); // 展开下一层
} else {
// 回退一步:把刚取出来的非Iterable元素“还回去”,并返回true
// 实现方式:用临时变量暂存,next()中直接返回
stack.push(new SingleItemIterator<>(next));
return true;
}
}
return false;
}
@Override
public E next() {
if (stack.isEmpty()) throw new NoSuchElementException();
Iterator<?> top = stack.pop();
Object item = top.next();
// 断言:这里 pop 出来的一定是 SingleItemIterator 或已确认为 E 类型
@SuppressWarnings("unchecked")
E result = (E) item;
return result;
}
// 辅助类:包装单个元素为 Iterator,用于“回退”机制
private static class SingleItemIterator<T> implements Iterator<T> {
private final T item;
private boolean used = false;
SingleItemIterator(T item) { this.item = item; }
@Override
public boolean hasNext() { return !used; }
@Override
public T next() {
if (used) throw new NoSuchElementException();
used = true;
return item;
}
}
}
使用方式:
List<Object> nested = Arrays.asList(
"a",
Arrays.asList(1, 2),
Arrays.asList(Arrays.asList("x", "y"), 3.14)
);
Iterator<Object> flat = new FlatIterator<>(nested);
while (flat.hasNext()) {
System.out.println(flat.next()); // 输出: a, 1, 2, x, y, 3.14
}
注意事项与优化点
该实现满足组合原则(不继承、仅持有 Iterator),但实际使用中需注意:
- 类型安全:Java 泛型擦除导致无法在运行时校验 E 是否匹配嵌套中的真实类型,调用方需确保数据结构一致,否则可能抛 ClassCastException
- remove() 方法:未实现(可抛 UnsupportedOperationException),因嵌套结构中“删除哪个层级的元素”语义不明确
- 空集合/空嵌套:代码已处理 null 和空 Iterable,不会 NPE
- 性能权衡:每次 next() 可能触发多层栈操作,但避免了预展开内存占用,适合大数据量、浅层嵌套场景
如需支持广度优先(BFS)顺序,可将 Deque 换成 Queue 并调整压入/弹出逻辑。

















