Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala - why map.size return 0 when the map is not empty

I am new to scala. Following example I am a bit confused what is going on. I created a mutable map, then pushed three key/value to the map. I can retrieve the queue with values by key, but "web.keys" it shows the map is empty, and "web.size" returns 0! why is this, and how can I retrieve the correct map size?

scala> import scala.collection.mutable.{Map, Set, Queue, ArrayBuffer}

scala> val web = Map[Int, Queue[Long]]().withDefaultValue(Queue()) 
web: scala.collection.mutable.Map[Int,scala.collection.mutable.Queue[Long]] = Map()

scala> web(123).enqueue(567L)

scala> web(123).enqueue(1L)

scala> web(123).enqueue(2L)

scala> web(123)
res96: scala.collection.mutable.Queue[Long] = Queue(567, 1, 2)

scala> web
res97: scala.collection.mutable.Map[Int,scala.collection.mutable.Queue[Long]] = Map()

scala> web.size
res98: Int = 0

scala> web.keys
res99: Iterable[Int] = Set()

A simple map works fine.

scala> val w= Map[Int,Int]()
w: scala.collection.mutable.Map[Int,Int] = Map()

scala> w(1)=1

scala> w
res10: scala.collection.mutable.Map[Int,Int] = Map(1 -> 1)

scala> w(2)=2

scala> w
res12: scala.collection.mutable.Map[Int,Int] = Map(2 -> 2, 1 -> 1)

scala> w.size
res13: Int = 2

I tried more experiment, seems it has something to do with "withDefaultValue". But how do I fix it?

scala> val ww= Map[Int,Int]().withDefaultValue(0) 
ww: scala.collection.mutable.Map[Int,Int] = Map()

scala> ww
res14: scala.collection.mutable.Map[Int,Int] = Map()

scala> ww(1) += 1

scala> ww(2) += 2

scala>  w.size
res17: Int = 0
like image 351
user1269298 Avatar asked Oct 13 '17 04:10

user1269298


1 Answers

When default value is returned from map it is not added to map! So when invoking web(123)

nothing is added to map, only default value is returned. Use getOrElseUpdate method to read data instead of using map with default value. Or simply take into consideration that default value is not in map as other key - value pairs.

I think you are misunderstanding your examples:

In first example web(123).enqueue(567L) you are retrieveing default value and adding 567L to default value (Queue). Nothing is added to map.

In second example w(1)=1 you are adding data to map

In third example ww(1) += 1 you are retrieving default value (0) and adding 1 to it.

In general using map(K) will return value for key K, while map(K) = V will set value V for key K.

Under the hood invoking map(K) and map(K) = V uses apply and update methods. See http://otfried.org/scala/apply.html or other scala documentation for more details.

like image 189
Piro Avatar answered Nov 14 '22 04:11

Piro