个人而言,我认为 java.util.Iterator 提供的功能范围相当有限。至少,我希望有以下方法:
- peek() 返回下一个元素但不移动迭代器
- previous() 返回上一个元素
当然还有许多其他可能性,例如 first() 和 last()。
是否有人知道这样的第三方迭代器存在吗?它可能需要作为 java.util.Iterator 的装饰器实现,以便与现有的 Java 集合一起工作。最好是具有“泛型意识”。
提前感谢, 唐
个人而言,我认为 java.util.Iterator 提供的功能范围相当有限。至少,我希望有以下方法:
当然还有许多其他可能性,例如 first() 和 last()。
是否有人知道这样的第三方迭代器存在吗?它可能需要作为 java.util.Iterator 的装饰器实现,以便与现有的 Java 集合一起工作。最好是具有“泛型意识”。
提前感谢, 唐
您可以通过使用 java.util.ListIterator
轻松获取 previous()
。
在那一点上进行查看可以通过执行以下操作轻松实现
public <T> T peek(ListIterator<T> iter) throws NoSuchElementException {
T obj = iter.next();
iter.previous();
return obj;
}
很不幸,由于每个集合类都实现了自己的迭代器,因此将其作为实用程序方法会更容易。要在某些接口(如MyListIterator
)上包装以获取每个集合的peek方法需要相当大的工作量。
我认为这些没有被实现的原因是它们对某些集合而言并不是简单的事情,并且会有较大的性能影响。但我认为对于那些你关心的集合,让这个工作起来应该很简单。
另外我也不喜欢Java迭代器没有办法获取当前值(因此无法根据值编写分支代码,只传递迭代器--你还必须传递你现在拥有的值)。
通常情况下,泛型运算符不会实现这些功能,因为并非所有容器都具备这些功能。一个典型的例子是表示某些外部数据输入的容器,例如将文件视为流。每次读取值时,您都会消耗它并将指针向前移动,无论您是否需要。如果您将这些约束强加于泛型迭代器,则会失去迭代器的泛型性。
如果您想要一个“previous”方法(如建议的),请使用ListIterator<>
,这将限制为行为类似于列表的容器。
我建议您查看Clojure中的Seq实现。
这些基础类的实现是用Java编写的,完整的源代码也是可用的。 Seq是Java迭代器上的装饰器(接收并实现Java迭代器接口)- 但它们还提供了自己的接口,这可能更符合您的需求 - 或者至少是一个起点。
public class Iterazor<T> {
private Iterator<T> it;
public T top;
public Iterazor(Collection<T> co) {
this.it = co.iterator();
top = it.hasNext()? it.next(): null;
}
public void advance() {
top = it.hasNext()? it.next(): null;
}
}
// usage
for(Iterazor<MyObject> iz = new Iterazor<MyObject>(MyCollection);
iz.top!=null; iz.advance())
iz.top.doStuff();
}
我从未遇到过需要使用peek()的问题;迭代器已经完全够用了。我很好奇您如何使用迭代器,以至于您感觉需要这个额外的功能。
peek()
和previous()
吗?PeekingIterator
支持peek()
但不支持previous()
。 - Phil