1

Below is a scala code to declare a immutable Map

var m:Map[Int,String] = Map(1->"hi",2->"hello")
println(m)
// Result: Map(1->"hi",2->"hello")

Here we are able to add or change the content of Map, then how can we say a map or list in scala are immutable

m=m+(3->"hey") 
println(m)
// Result: Map(1->"hi",2->"hello",3->"hey")**
Mario Galic
  • 47,285
  • 6
  • 56
  • 98
Abhinav Kumar
  • 210
  • 3
  • 13

2 Answers2

8

Map is immutable, but you used a mutable variable m (because you declare it as var).

This line m=m+(3->"hey") actually creates a new map and assigned it to your variable m.

Try to declare m as val and see that you will get a compilation error.

But - if you will use mutable map:

val m = scala.collection.mutable.Map[Int,String]

You will be able to update this map (while you can't do this with immutable map) -

m(3) = "hey"

or

m.put(3,"hey")

This is how you will update the content of the map, without recreating it or changing the variable m (like you did before with m = m + ...), because here m is declared as val, which makes it immutable, but the map is mutable.

You still can't do m = m + .. when it's declared as val.

Please refer to this answer about the differences between var and val.

Gal Naor
  • 2,397
  • 14
  • 17
  • Anything declared as Val will be immutable. Even if u declare a Mutable map like below, it will be immutable val m=scala.collection.mutable.Map((1->"hi",2->"hello") – Abhinav Kumar Jul 08 '19 at 06:09
  • My question is not about Val and Var, its regarding Immutability of Scala Map/List. Scala doc says Map are Immutable. – Abhinav Kumar Jul 08 '19 at 06:13
  • Updating my answer - anyway it's better to avoid using `var` if you want to keep your variables immutables. (of course, unless you are using mutable collections) – Gal Naor Jul 08 '19 at 06:16
  • Sorry, I still did not get answer to this question. – Abhinav Kumar Jul 08 '19 at 06:20
  • 1
    Updated my answer again, I hope it's more clear now. – Gal Naor Jul 08 '19 at 06:22
  • 1
    @AbhinavKumar Your first comment is incorrect; `mutable.Map` is mutable even when assigned to a `val`. – Tim Jul 08 '19 at 10:36
3

Even if you think that your question is not about var or val, it actually is: in your example it is very important whether m is defined as var or val. In your example, even though you see that the map has changed, it actually has not: your code creates another map and assigns it to the same variable. The map itself has not changed, because it is immutable. You can observe this in this code:

val m1 = Map(1 -> "hi", 2 -> "hello")

var m = m1
m = m + (3 -> "hey")

println(m)   // prints Map(1 -> ..., 2 -> ..., 3 -> ...)
println(m1)  // prints Map(1 -> ..., 2 -> ...)

If Map was mutable here, you would have seen that m1 has also changed. Because you don't see this, it means that the map is not mutable, only the variable is.

Vladimir Matveev
  • 120,085
  • 34
  • 287
  • 296
  • Why would M1 change here when you have changed M( m=m+(3->"hey") ). Please verify your answer once. – Abhinav Kumar Jul 08 '19 at 06:31
  • 1
    @AbhinavKumar Because right after `var m = m1` both `m` and `m1` are pointing at the same data. – Mario Galic Jul 08 '19 at 10:11
  • @AbhinavKumar that is the point, actually - `m1` will *not* change. If `Map` was mutable, and the `m = m + ...` changed `m`, then because `m1` and `m` before the change point to the same object, you would have seen `m1` change as well. It does not happen, which implies that `Map` is immutable. – Vladimir Matveev Jul 08 '19 at 18:18