11.6. Using Stream, a Lazy Version of a List
Problem
You want to use a collection that works like a List
but invokes its transformer methods
(map
, filter
, etc.) lazily.
Solution
A Stream
is like a List
, except that its elements are computed
lazily, in a manner similar to how a view creates a
lazy version of a collection. Because Stream
elements are computed lazily, a
Stream
can be long ... infinitely
long. Like a view, only the elements that are accessed are computed.
Other than this behavior, a Stream
behaves similar to a List
.
Just like a List
can be
constructed with ::
, a Stream
can be constructed with the #::
method, using Stream.empty
at the end of the expression
instead of Nil
:
scala> val stream = 1 #:: 2 #:: 3 #:: Stream.empty
stream: scala.collection.immutable.Stream[Int] = Stream(1, ?)
The REPL output shows that the stream begins with the number
1
but uses a ?
to denote the end of the stream. This is
because the end of the stream hasn’t been evaluated yet.
For example, given a Stream
:
scala> val stream = (1 to 100000000).toStream
stream: scala.collection.immutable.Stream[Int] = Stream(1, ?)
you can attempt to access the head and tail of the stream. The head is returned immediately:
scala> stream.head
res0: Int = 1
but the tail isn’t evaluated yet:
scala> stream.tail
res1: scala.collection.immutable.Stream[Int] = Stream(2, ?)
The ?
symbol is the way a lazy
collection shows that the end of the collection hasn’t been evaluated
yet.
As discussed in Recipe 10.24, transformer methods are computed ...
Get Scala Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.