为什么标准的Java迭代器没有peek()?

时间:2018-08-30 23:48:32

标签: java iterator

对Java迭代器进行编程时,是否没有使其像peek()这样的函数有什么特殊原因,该函数会在不推进迭代器的情况下返回下一个元素?

3 个答案:

答案 0 :(得分:14)

  

为什么标准的Java迭代器没有peek()?

  1. 因为peek()不是Iterator设计模式的核心功能。

  2. 因为绝大多数迭代器用例都不需要它。强迫所有实现(包括无数的自定义/第三方类)实施不必要的方法将是一个坏主意。

  3. 因为peek()方法会对惰性...源的迭代器的语义产生潜在影响。

  4. 由于实现peek()在某些情况下会影响迭代器的效率(内存,CPU)。无论您是否实际使用它。

  5. 因为peek()在某些晦涩的情况下会导致内存泄漏。

  6. 因为...吻。

但是最终,真正的原因是……因为他们早在2000年就以这种方式进行了设计。当设计辩论发生时,我们不在会议室 1

1-就其价值而言,似乎大多数 2 其他语言也对其标准迭代器API做出了相同的决定。 Rust似乎是个例外。参见https://doc.rust-lang.org/std/iter/struct.Peekable.html

2-...基于使用Google搜索的高度不科学的“调查”。


如果您还需要提供peek()的迭代器抽象,则可以扩展Iterator接口并自己实现迭代器。确实,可以将通用的带迭代器的迭代器轻松实现为常规Iterator的包装器。

或寻找第三方API /实施;例如GuavaApache Commons

答案 1 :(得分:1)

如果您确实需要使用peek()进行迭代,为什么不使用LinkedList作为初始数据结构?它提供.peek().pop()来检索头部。

答案 2 :(得分:0)

以下示例使用peek方法实现了迭代器。 remove的实现留给读者。

import java.util.Iterator;

/**
 * An Iterator with a peek method for just one value.
 */
public class PeekIterator<T> implements Iterator<T>
{
  private Iterator<T> iterator;

  public PeekIterator (Iterator<T> iterator) { this.iterator = iterator; }

  private boolean peeked = false;
  private T peeked_value = null;

  public boolean hasNext () { return iterator.hasNext (); }

  public T next ()
  {
    T value;
    if (peeked) {
      peeked = false;
      value = peeked_value;
    }
    else
      if (iterator.hasNext ())
        value = iterator.next();
      else
        value = null;
    return value;
  }

  public T peek ()
  {
    T value;
    if (peeked)
      value = peeked_value;
    else {
      peeked = true;
      if (iterator.hasNext ())
        peeked_value = iterator.next ();
      else
        peeked_value = null;
      value = peeked_value;
    }
    return value;
  }
}