改进的集合迭代器



就我个人而言,我发现java.util.Iterator提供的功能范围相当可怜。至少,我希望有这样的方法:

  • peek()返回下一个元素而不向前移动迭代器
  • previous()返回上一个元素

尽管还有很多其他的可能性,比如first()和last()。

有人知道这样的第三方迭代器是否存在吗?它可能需要作为java.util.Iterator的装饰器来实现,这样它才能与现有的java集合一起工作。理想情况下,它应该是"有泛型意识的"。

提前感谢,Don

只需使用java.util.ListIterator即可轻松获得previous()

通过进行可以很容易地实现在该点上的窥视

public <T> T peek(ListIterator<T> iter) throws NoSuchElementException {
    T obj = iter.next();
    iter.previous();
    return obj;
}

不幸的是,将它作为一个实用方法会更容易,因为每个集合类都实现了自己的迭代器。要在MyListIterator等接口上为每个集合创建一个peek方法的包装器,需要做大量的工作。

Apache Commons Collections

谷歌收藏

我认为没有实现这些功能的原因是,它们对于某些集合来说并不重要,并且会对性能产生很大影响。我认为对你来说,为你关心的藏品制作这件作品会很简单。

我也不喜欢Java迭代器在不移动当前值的情况下无法获得当前值(因此,您不能简单地编写基于该值的分支代码,只传递迭代器——您还必须传递现在的值)。

泛型运算符没有实现这些功能有一个很好的原因:它们并不适用于所有容器。典型的例子是一个表示一些外部数据输入的容器,比如一个被视为流的文件。每次读取值时,都会消耗并向前移动指针(无论是否需要)。如果您将这些约束强加给通用迭代器,那么您就失去了迭代器的通用性。

如果您想要previous方法,如建议的那样,请使用ListIterator<>,然后它被限制为表现为列表的容器。

我要看的一件事是clojure 中的Seq实现

http://clojure.org/sequences

基类的实现是用Java实现的,并且可以获得完整的源代码。Seq是java迭代器的装饰器(采用并实现java迭代程序接口),但它们也提供了自己的接口,这可能更符合您的需求,或者至少是一个起点。

我看到有人链接到Google Collections,但没有人提到你正在寻找的方法名为Iterators.peekingIterator().

尽管如此,如果您可以只使用ListIterator,那将是最好的。

正如ykaganovich所建议的,您可能想要查看谷歌收藏的内容。对于你想要的一些事情,比如偷看,肯定有一些支持。此外,正如其他一些人所提到的,从可能性或性能的角度来看,为所有集合实现所有这些东西可能是危险的。

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()的问题;迭代器对我来说运行得很好。我很好奇你是如何使用迭代器的,你觉得你需要这个额外的功能。

听起来使用Stack可能会更好。

编写Java集合是为了提供一组最小的有用功能。对于任何实现Java的人都可以实现具有的代码,这是一种非常好的方法。用可能有用的功能扩充接口可以导致代码量的大幅增加,而只有少数人注意到了改进。如果peek()和previous()是标准迭代器的一部分,这意味着每个编写新型Collection的人都必须实现它,无论它是否合理。

迭代程序还被设计用于处理物理上不能倒退的事情,这使得peek()和previous()都不可能。

最新更新