java iterator 遍历访问者模式通过将迭代逻辑与数据结构解耦,实现了对集合元素的统一访问和扩展操作。具体做法是定义一个包含 next() 和 hasnext() 方法的 iterator 接口,并在自定义集合类中实现该接口以返回迭代器实例。这样可以在不修改集合内部结构的前提下,支持多种遍历策略(如顺序、逆序)或结合访问者模式执行不同操作。

如何为自定义集合实现 Iterator 接口
要实现自定义集合的迭代功能,需让集合类实现 Iterable<t></t> 接口,并编写一个内部类或独立类实现 Iterator<t></t>。核心是维护当前索引或指针,在 next() 中返回元素并推进状态,在 hasNext() 中检查是否越界。若集合支持并发修改检测,还需记录 modCount 以防 ConcurrentModificationException。

import java.util.Iterator;
import java.util.NoSuchElementException;
public class CustomList<T> implements Iterable<T> {
private T[] items;
private int size;
private int modCount = 0;
@SuppressWarnings("unchecked")
public CustomList(int capacity) {
items = (T[]) new Object[capacity];
}
public void add(T item) {
if (size == items.length) throw new RuntimeException("Full");
items[size++] = item;
modCount++;
}
@Override
public Iterator<T> iterator() {
return new CustomIterator();
}
private class CustomIterator implements Iterator<T> {
private int cursor = 0;
private int expectedModCount = modCount;
@Override
public boolean hasNext() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
return cursor < size;
}
@Override
public T next() {
if (!hasNext()) throw new NoSuchElementException();
return items[cursor++];
}
}
}
使用示例:输入新创建的 CustomList<string></string>,依次添加 "A"、"B"、"C",调用 iterator() 后通过增强 for 循环遍历,预期输出为 A、B、C。验证 hasNext() 在末尾返回 false,next() 抛出异常。若在迭代中调用 add(),会触发 ConcurrentModificationException。
立即学习“Java免费学习笔记(深入)”;
如何结合访问者模式对遍历元素执行多态操作
将 Iterator 与访问者模式结合时,迭代器负责提供元素序列,而每个元素接受一个访问者对象来执行特定行为。需定义 Visitor 接口及其方法(如 visit(Element e)),元素类实现 accept(Visitor v) 方法。遍历时,迭代器逐个取出元素并调用其 accept(thisVisitor),从而实现操作与结构的分离。适用于需要频繁新增操作类型但元素结构稳定的场景。

interface Visitor {
void visit(StringElement e);
void visit(IntegerElement e);
}
abstract class Element {
abstract void accept(Visitor v);
}
class StringElement extends Element {
String value;
StringElement(String v) { value = v; }
@Override void accept(Visitor v) { v.visit(this); }
}
class IntegerElement extends Element {
int value;
IntegerElement(int v) { value = v; }
@Override void accept(Visitor v) { v.visit(this); }
}
public class CompositeCollection implements Iterable<Element> {
private List<Element> elements = new ArrayList<>();
public void add(Element e) { elements.add(e); }
@Override
public Iterator<Element> iterator() {
return elements.iterator();
}
}
// 使用示例
CompositeCollection coll = new CompositeCollection();
coll.add(new StringElement("Hello"));
coll.add(new IntegerElement(42));
Visitor printer = new Visitor() {
public void visit(StringElement e) { System.out.println("Str: " + e.value); }
public void visit(IntegerElement e) { System.out.println("Int: " + e.value); }
};
for (Element el : coll) {
el.accept(printer);
}
输入:集合含一个 StringElement("Hello") 和一个 IntegerElement(42),访问者打印类型前缀。预期输出两行:"Str: Hello" 和 "Int: 42"。验证访问者未直接依赖元素类型判断,而是通过双分派实现多态。若新增 DoubleElement,只需扩展 Visitor 接口和元素类,无需修改现有遍历逻辑。
当 Iterator 被多次调用时是否会重置遍历状态
每次调用 iterator() 都会创建一个新的迭代器实例,因此多次调用不会共享状态,也不会重置已有迭代器的位置。每个迭代器独立维护自己的游标和修改计数。这意味着可以对同一集合并行获取多个迭代器,分别进行遍历,互不影响。但若在某个迭代器遍历过程中修改了集合结构,其他活跃迭代器可能抛出 ConcurrentModificationException。


















