12

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

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

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

有谁知道这样的第 3 方迭代器是否存在?它可能需要实现为 java.util.Iterator 的装饰器,以便它可以与现有的 java 集合一起使用。理想情况下,它应该是“泛型意识”。

在此先感谢,唐

4

11 回答 11

11

只需previous()使用java.util.ListIterator.

窥视这一点很容易通过执行

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

不幸的是,将它作为一种实用方法会更容易,因为每个集合类都实现了自己的迭代器。做一个包装器以在某些接口上的每个集合上获取一个 peek 方法,例如MyListIterator将是相当多的工作。

于 2008-10-10T17:53:43.357 回答
8

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

我也不喜欢 Java 迭代器无法在不移动它的情况下获取当前值(因此你不能轻易地编写基于值分支的代码,只需传递迭代器——你必须传递你的值现在也有)。

于 2008-10-10T17:56:50.103 回答
8

Apache Commons 集合

谷歌收藏

于 2008-10-10T18:35:20.307 回答
4

通用运算符没有实现这些特性是有一个很好的理由:它们并不适用于所有容器。典型的例子是一个代表一些外部数据输入的容器,比如一个被视为流的文件。每次您读取一个值时,您都会使用它并将指针向前移动,无论您是否愿意。如果你对泛型迭代器施加这些约束,那么你就会失去迭代器的泛型性。

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

于 2008-10-10T18:48:31.217 回答
3

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

http://clojure.org/sequences

基类的实现是用 Java 实现的,并且可以使用完整的源代码。Seq 是 Java 迭代器上的装饰器(采用并实现 Java 迭代器接口)——但它们也提供自己的接口,这可能是你想要的更多——或者至少是一个起点。

于 2008-10-10T18:00:09.257 回答
2

我看到有人链接到Google Collections,但是没有人提到您要查找的方法称为Iterators.peekingIterator()。

不过,最好只使用 ListIterator。

于 2009-11-04T01:56:17.167 回答
1

正如 ykaganovich 建议的那样,您可能想查看google-collections 的东西。你想要的一些东西肯定有一些支持,比如偷看。此外,正如其他一些人所提到的,从可能性或性能的角度来看,为所有集合实现所有这些东西可能是危险的。

于 2008-10-10T18:51:00.120 回答
1
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();
}
于 2009-03-05T05:49:13.760 回答
0

我从来没有遇到过需要 peek(); 的问题。迭代器对我来说工作得很好。我很好奇你是如何使用你觉得你需要这个附加功能的迭代器的。

于 2008-10-10T17:59:14.063 回答
0

听起来你最好使用堆栈。

于 2008-10-10T18:38:22.720 回答
0

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

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

于 2008-11-18T16:33:24.963 回答