イテレータバッファ付きイテレータ目次

バッファ付きイテレータ

「先読み」ができ、次に返される要素を飛ばさずに調べられるイテレータが欲しくなる場合があります。 文字列の列を返すイテレータから先頭の空文字列を飛ばす例を考えてみましょう。 以下のように書きたくなるかもしれません:

def skipEmptyWordsNOT(it: Iterator[String]) =
  while (it.next().isEmpty) {}

しかしこのコードをもっと良く見てみると、これは間違いだと分かります: コードは確かに先頭の空文字列を飛ばしますが、メソッドはitを最初の空でない文字列の次へとさらに進めてしまうのです!

この問題の解決方法はバッファ付きイテレータを使うことです。 BufferedIteratorクラスはIteratorの子クラスで、1つ追加のメソッドheadを提供します。 バッファ付きイテレータのheadの呼び出しは最初の要素を返しますがイテレータを前へ進めません。 バッファ付きイテレータを使うと、空文字列を飛ばす処理は次のように書けます。

def skipEmptyWords(it: BufferedIterator[String]) =
  while (it.head.isEmpty) { it.next() }

全てのイテレータはbufferedメソッドを呼ぶとバッファ付きイテレータに変換できます。 これは例です:

scala> val it = Iterator(1234)
it: Iterator[Int] = non-empty iterator
scala> val bit = it.buffered
bit: java.lang.Object with scala.collection.
   BufferedIterator[Int] = non-empty iterator
scala> bit.head
res10: Int = 1
scala> bit.next()
res11: Int = 1
scala> bit.next()
res11: Int = 2

バッファ付きイテレータbitheadの呼び出しはイテレータを進めていないことに注意してください。 そのため、次のbit.next()の呼び出しはbit.headと同じ値を返します。

続いては: コレクションをゼロから作成する


イテレータバッファ付きイテレータ目次