あるプログラマの日記

プログラマのメモ、出来事、考えたこと、勉強とかの雑記

Stream

Listとほぼ同じで、違いは実際に要素が指定されるまで作成が遅延される。
要素が無限に続くリストや要素数を事前に決められないリストとして表現できる。

Stream.cons は List の :: と同じように 先頭要素とリスト(Stream)を連結する。
cons は Streamコンパニオンオブジェクトのオブジェクト。

scala> def from(start: Int): Stream[Int] = Stream.cons(start, from(start + 1))
foo: (start: Int)Stream[Int]

scala> from(1).take(3).foreach(println)
1
2
3

最初に要素を指定して作成することもできる。*1
contains で要素の有無を確認できるが、無限リストの状態では、まだ追加していない要素を contains すると結果が返されないのでやってはダメ*2。放置すると OutOfMemoryError が発生。

scala> val bar = Stream(3, 4, 5)
bar: scala.collection.immutable.Stream[Int] = Stream(3, ?)

scala> bar(1)
res2: Int = 4

scala> bar(2)
res3: Int = 5

scala> bar.contains(3)
res4: Boolean = true

scala> bar.contains(2)
res5: Boolean = false

scala> val bar2 = from(5)
bar6: Stream[Int] = Stream(5, ?)

scala> bar2.contains(0)
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:2882)
	at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
..snip..

Stream.cons は、Streamコンパニオンオブジェクトの #:: オブジェクトを使って書くことも可能

scala> Stream.cons(1, Stream.cons(2, Stream.empty)).print
1, 2, empty

scala> (1 #:: 2 #:: Stream.empty).print
1, 2, empty

*1:これは、Stream を使用する意味があまりないような...

*2:当然といえば当然