イテレータ バッファ付きイテレータ 目次
最新版は Scala Documentation に移行しました。

バッファ付きイテレータ

イテレータを前進させずに次に返る要素を検査できるような「先読み」できるイテレータが必要になることがたまにある。例えば、一連の文字列を返すイテレータがあるとして、その最初の空白文字列を飛ばすという作業を考える。以下のように書こうと思うかもしれない。

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

しかし、このコードを慎重に見ると間違っていることが分かるはずだ。コードは確かに先頭の空白文字列の続きを読み飛ばすが、it は最初の非空白文字列も追い越してしまっているのだ。

この問題はバッファ付きイテレータを使うことで解決できる。BufferedIterator トレイトは、head というメソッドを追加で提供する Iterator の子トレイトだ。バッファ付きイテレータに対して 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

バッファ付きイテレータに対して head を呼び出してもイテレータ bit は前進しないことに注意してほしい。よって、後続の bit.next() の呼び出しは bit.head と同じ値を返す。

続いては、コレクションの作成


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