Java.use(better); Episode#22 ファインダーを作成する
《前の記事|記事一覧|次の記事》
Java.use(better, Scala);
Episode#22ファインダーを作成する:履歴を残す
@父親が、子供達にできる最も重要なことは
@子供達の母親を愛することだ
The most important thing a father can do for his children is to love their mother.
Theodore Hesburgh - Wikipedia
《関連記事》
┃余録:trait Iterator
trait Iterator を再利用すると、少数の抽象メソッド hasNext/next を実現するだけで、多彩な機能を利用できます。
trait Iterator[+A] extends TraversableOnce[A] { def hasNext: Boolean def next(): A
メソッド hasNext は、まだ巡回していない要素があるかを判定します。次に next を呼び出したとき、要素が得られるなら true を、それ以外は false を返します。メソッド next は、次に巡回する要素を返します。ただし、hasNext が true を返さないときには、その動作を保証しません。
■ メソッド foreach
構造化プログラミングの「条件反復」に代わる、メソッド foreach の動作を規定します。
def foreach[U](f: A => U) { while (hasNext) f(next()) }
注目に値するのは、抽象メソッド hasNext/next だけで実現されているので、具象クラスに依存しない「抽象表現」になっていることです。まだ巡回していない要素がある hasNext かぎりは、次に巡回する要素 next() に特定の関数 f を適用します。これは、構造化プログラミングの「条件反復」に相当します。
while (条件式) 任意の処理(各要素)
つまり、メソッド foreach は、条件を規定する hasNext と、要素を取り出す next に「要素分解」できるのが分ります。
この抽象表現を「テンプレート」と見なすなら、具象クラスごとに最適化されたメソッド hasNext/next の本体が、そこにインライン展開されることに相当します。必要なら、具象クラスごとに最適化したメソッド foreach を再定義します。
■ メソッド map
各要素に関数を適用して得られる、新たな要素を列挙します。
def map[B](f: A => B): Iterator[B] = new AbstractIterator[B] { def hasNext = self.hasNext def next() = f(self.next()) }
ここで、抽象クラス AbstractIterator は、
private[scala] abstract class AbstractIterator[+A] extends Iterator[A]
trait Iterator で規定した機能を具現したいときに利用します。
これも、抽象メソッド hasNext/next だけで実現されているので、具象クラスに依存しない抽象表現です。条件を規定する hasNext は、self.hasNext に代わるものです。要素を取り出す next は、self.next から得られる要素に、特定の関数 f を適用するだけです。
■ メソッド zip
他のイテレーターと組み合わせて、各要素(タプル)に関数を適用して得られる、新たなタプルを列挙します。どちらか一方の要素が見つからないと、他方の要素も無視します。
def zip[B](that: Iterator[B]): Iterator[(A, B)] = new AbstractIterator[(A, B)] { def hasNext = self.hasNext && that.hasNext def next = (self.next, that.next) }
これも、具象クラスに依存しない抽象表現です。条件を規定する hasNext は、self.hasNext および that.hasNext に代わるものです。要素を取り出す next は、self.next および that.next を要素とするタプルを生成します。
》作業中です《
↑ TOP