java中实现双向迭代需返回listiterator:1.推荐自定义类实现list接口并委托listiterator();2.若不实现list,须手动实现listiterator,维护游标与索引;3.注意不能仅靠重写iterator(),需提供listiterator()方法,且previous()在单向结构中可能低效。

在 Java 中为自定义数据结构实现双向迭代(即支持 next() 和 previous()),核心是让该结构返回一个实现了 ListIterator 接口的迭代器,而非仅实现基础的 Iterator。
1. 自定义数据结构需实现 List 接口(推荐)
最直接的方式是让你的类继承或组合一个标准 List(如 ArrayList 或 LinkedList),或直接实现 List 接口。因为只有 List 及其子类型能自然支持 ListIterator —— 这是 Java 规范明确要求的:
-
List.iterator()返回普通Iterator -
List.listIterator()和List.listIterator(int index)返回ListIterator,支持双向遍历、添加、修改、获取索引等
例如,封装一个简单容器:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
public class MyList<e> implements List<e> {
private final List<e> delegate = new ArrayList();
// 实现所有 List 方法(委托给 delegate)...
@Override
public ListIterator<e> listIterator() {
return delegate.listIterator();
}
@Override
public ListIterator<e> listIterator(int index) {
return delegate.listIterator(index);
}
}</e></e></e></e></e>
2. 若不实现 List,手动实现 ListIterator
如果数据结构无法/不适合实现 List(比如链表节点自管理、跳表、树形结构等),可内部定义一个私有类实现 ListIterator<e></e>。关键点包括:
- 维护当前游标位置(
cursor),区分“上一个返回元素”和“下一个待返回元素” - 正确处理
hasNext()/hasPrevious()边界(如空集合、首尾位置) -
next()向后移动并返回;previous()向前移动并返回 -
nextIndex()和previousIndex()需返回逻辑索引(不是物理指针) - 若支持修改,还需实现
add()、set()、remove()
示例(简化版单向链表的双向迭代器):
private static class Node<e> {
E data;
Node<e> next;
// 若为双向链表,还需 prev 字段
}
private class LinkedListListIterator implements ListIterator<e> {
private Node<e> current;
private Node<e> lastReturned;
private int index; // 当前逻辑索引(从 0 开始)
LinkedListListIterator(Node<e> head) {
this.current = head;
this.index = 0;
}
@Override
public boolean hasNext() {
return current != null;
}
@Override
public E next() {
if (!hasNext()) throw new NoSuchElementException();
lastReturned = current;
E item = current.data;
current = current.next;
index++;
return item;
}
@Override
public boolean hasPrevious() {
return lastReturned != null && lastReturned != head; // 需结合具体结构判断
}
@Override
public E previous() {
if (!hasPrevious()) throw new NoSuchElementException();
// 此处需能反向遍历(如用双向链表)或回溯查找(低效,不推荐)
// 真实场景建议底层用双向链表或缓存前驱引用
throw new UnsupportedOperationException("Not implemented for singly-linked");
}
// 其他方法略...
}</e></e></e></e></e></e>
3. 关键注意事项
-
ListIterator是Iterator的子接口,但 不能仅靠重写iterator()方法返回ListIterator:调用方若只用Iterator接口,就无法访问previous()等方法 - 若坚持不实现
List,对外提供两个独立方法更清晰:iterator()和descendingIterator()(参考TreeSet的设计) - 线程安全:自定义
ListIterator需自行保证 fail-fast 行为(检查 modCount)或明确声明非线程安全 - 性能:双向遍历在非双向结构(如单向链表)上实现
previous()可能需 O(n) 回溯,应权衡是否值得
4. 使用示例
无论哪种实现,使用方式一致:
MyList<string> list = new MyList();
list.add("a"); list.add("b"); list.add("c");
// 前向遍历
for (String s : list) {
System.out.print(s + " "); // a b c
}
// 后向遍历(必须用 ListIterator)
ListIterator<string> lit = list.listIterator(list.size());
while (lit.hasPrevious()) {
System.out.print(lit.previous() + " "); // c b a
}</string></string>
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










