Stream
Streamは要素が必要になったときに作成されるList(みたいなモノ)です。
- 要素は必要になったときに初めて作成されるので、
- 要素の作成に時間がかかる場合に初期作成コストを抑えることができます。
- また、要素を全部辿らない場合に無駄な作成コストを削減できます。
- JavaのInputStreamとかとは何の関係もありません。
サンプル。
println( "\n--- use range" ) // Streamを使って任意の範囲の整数を持つListを作る関数 def rangeUseStream( last:Int ):Stream[Int] = { def next( current:Int):Stream[Int] = { println( "next :" + current ) // いつ呼び出されたかわかるように if (current == last) Stream.empty else Stream.cons(current, next(current+1)) } next( 0 ) } rangeUseStream(5).foreach( i => println(i) ) println( "\n--- use list" ) // Listを使って任意の範囲の整数を持つListを作る関数 def rangeUseList( last:Int ):List[Int] = { def next( current:Int ):List[Int] = { println( "next :" + current ) // いつ呼び出されたかわかるように if (current == last) Nil else current :: next(current+1) } next( 0 ) } rangeUseList(5).foreach( i => println(i) )
実行結果です。Streamを使った方は要素が遅延作成されているのがわかります。
--- use range next :0 0 next :1 1 next :2 2 next :3 3 next :4 4 next :5 --- use list next :0 next :1 next :2 next :3 next :4 next :5 0 1 2 3 4
ちなみに、長さを取得するとすべての要素が一気に作成されてしまいます。
println( rangeUseStream(5).length)
実行結果です。
next :0 next :1 next :2 next :3 next :4 next :5 5
動作としては納得できますが、使うときには気をつけないとだめだな。