首先,如果有更多的元素,Iterator的契约要求hasNext返回true,如果hasNext()== false,则next抛出异常.
这意味着有两种使用迭代器的方式:while(it.hasNext())it.next()和try {while(true)it.next(); } catch ….后者不是一个好习惯,但必须得到支持.我之所以提到这一点是因为你不能依赖于之前调用过的hasNext.我发现这个要求通常是迭代器实现中不必要的复杂性的罪魁祸首.
我的选择是使用具有下一个值的局部变量.如果next == null,则下一个值未知(并且我们必须找到它),或者我们已经到达迭代的末尾(hasNext()将返回false而next()将失败).还要考虑当下一个值未知时,我们可能在迭代结束时,但我们还没有实现它.
Node next;
public boolean hasNext() {
//if the next value already known, do nothing
if (next==null) {
//otherwise lookup the next value
next=findNext();
}
//return true if the next value was found
return next!=null;
}
public Node next() {
if (next==null&&!hasNext()) {
//here we have reached the end of the iteration
throw new NoSuchElementException();
} else {
//either we alredy knowed the next element
//or it was found by hasNext
Node result = next;
next=null;
return result;
}
}
private Node findNext() {
//the actual iteration
}
关于有序遍历的情况,你应该保持一个堆栈(请注意,Stack的实现是基于数组的并且是同步的,可探测的是使用Dequeue这样的更好,例如LinkedList,它也支持Java 6中的push和pop. ),以及每次调用findNext时知道如何恢复迭代的辅助状态.