「無限」イテレータは悪い設計ですか? [closed] 質問する

「無限」イテレータは悪い設計ですか? [closed] 質問する

Iterator「無限」の実装、つまりhasNext()always(*) の呼び出しが true を返す実装を提供することは、一般的に悪い習慣だと考えられていますか?

通常、呼び出しコードが不規則に動作する可能性があるため「はい」と答えますが、以下の実装では、hasNext()呼び出し元がイテレータが初期化されたリストからすべての要素を削除しない限り、trueを返します。つまり、終了条件があるこれは の正当な使用法だと思いますかIterator? 直感に反すると主張する人もいるかもしれませんが、契約に違反しているようには思えません。

public class CyclicIterator<T> implements Iterator<T> {
  private final List<T> l;
  private Iterator<T> it;

  public CyclicIterator<T>(List<T> l) {
    this.l = l;
    this.it = l.iterator();
  }

  public boolean hasNext() {
    return !l.isEmpty();
  }

  public T next() {
    T ret;

    if (!hasNext()) {
      throw new NoSuchElementException();
    } else if (it.hasNext()) {
      ret = it.next();
    } else {
      it = l.iterator();
      ret = it.next();
    }

    return ret;
  }

  public void remove() {
    it.remove();
  }
}

(衒学的)編集

Iteratorフィボナッチ数列などの無限数列から値を生成するために Iterator をどのように使用できるかについてコメントする人もいます。ただし、JavaIteratorドキュメントでは Iterator について次のように説明されています。

コレクションの反復子。

java.util.Collectionフィボナッチ数列は無限コレクションであると主張することもできますが、Java ではコレクションを、コレクションが制限付きでなければならないことを暗示するなどのメソッドを提供するインターフェースと同一視します。したがって、制限なしのシーケンスから値を生成するジェネレーターとしてsize()使用することは正当でしょうか?Iterator

ベストアンサー1

それはそうですね完全に合法- はIterator単なる「もの」のストリームです。ストリームはなぜ必ず境界を定める必要があるのでしょうか?

他の多くの言語(例えばScala)には、無制限のストリームの概念が組み込まれており、これらを反復処理することができます。例えば、scalazを使用すると

scala> val fibs = (0, 1).iterate[Stream](t2 => t2._2 -> (t2._1 + t2._2)).map(_._1).iterator
fibs: Iterator[Int] = non-empty iterator

scala> fibs.take(10).mkString(", ") //first 10 fibonnacci numbers
res0: String = 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

編集: 驚きを最小にする原則に関しては、完全にコンテキストに依存すると思います。たとえば、このメソッドが返す結果は何になると思いますか?

public Iterator<Integer> fibonacciSequence();

おすすめ記事