Reputation: 53816
In below code I'm testing my understanding of Scala lazy evaluation.
I'm attempting process a collection just once within a function definition. But as can be seen below processMap
is invoked multiple tiems. Should it not just be invoked once ?
val a = Array( ("1" , "1") , ("2" , "2")) //> a : Array[(String, String)] = Array((1,1), (2,2))
def toLazyMapDef(aparam : Array[(String, String)]) = {
lazy val toMap = processMap(aparam)
toMap
} //> toLazyMapDef: (aparam: Array[(String, String)])scala.collection.immutable.Ma
//| p[String,String]
def processMap(aparam : Array[(String, String)]) = {
println("in processMap")
aparam.toMap
} //> processMap: (aparam: Array[(String, String)])scala.collection.immutable.Map[
//| String,String]
println(toLazyMapDef(a)) //> in processMap
//| Map(1 -> 1, 2 -> 2)
println(toLazyMapDef(a)) //> in processMap
//| Map(1 -> 1, 2 -> 2)
println(toLazyMapDef(a)) //> in processMap
//| Map(1 -> 1, 2 -> 2)
Upvotes: 1
Views: 121
Reputation: 12563
Here, the lazy val toMap is an internal variable for the function. It is not preserved between the function calls. This might be a better example (we have lazy val as a class member, and we can demonstrate that it's only evaluated once):
case class LazyMapDemo(aparam : Array[(String, String)]) {
lazy val toMap = processMap(aparam)
def giveLazyMap = toMap
def processMap(aparam : Array[(String, String)]) = {
println("in processMap")
aparam.toMap
}
}
scala> val a = Array( ("1" , "1") , ("2" , "2"))
a: Array[(String, String)] = Array((1,1), (2,2))
scala> val ld = LazyMapDemo(a)
ld: LazyMapDemo = LazyMapDemo([Lscala.Tuple2;@63f5faaa)
scala> ld.toMap
in processMap
res0: scala.collection.immutable.Map[String,String] = Map(1 -> 1, 2 -> 2)
scala> ld.toMap // processMap not called
res1: scala.collection.immutable.Map[String,String] = Map(1 -> 1, 2 -> 2)
scala> ld.giveLazyMap // processMap not called
res2: scala.collection.immutable.Map[String,String] = Map(1 -> 1, 2 -> 2)
Upvotes: 4