Reputation: 223
Why this
import java.util.HashMap
val hm = new HashMap[String, String]()
hm.put("hello", "bye")
hm.get("hello")
// res1: String = bye
does not pose any problem even though hm is supossed to be immutable. What am I missing?
Thanks in advance
Upvotes: 1
Views: 265
Reputation: 96
While there are a few answers that do a good job of pointing out that there is a difference between an immutable reference and an immutable object, I feel that they miss the key element to help a Java developer understand what is going on. A val
declaration in Scala is just like a const
declaration in Java, nothing more. So when you declare
val hm = new HashMap[String, String]()
it is equivalent to the Java declaration of
const HashMap<String, String> hm = new HashMap<>();
In both cases, the new object can be mutated, but the reference to it can't be.
The reality is that people should be using const
a lot more in Java, but they don't because adding those extra characters takes more effort. The decision to use val
and var
in Scala effectively removes the cost for declaring const
references. Of course, this only really gives you complete immutability when you pair it with the immutable types that are part of the Scala libraries. I have a video in the playlist https://www.youtube.com/playlist?list=PLLMXbkbDbVt8-dcRqxgdimPtn0bsP_A6W with the title "Mutability and Aliasing" that shows in a graphical way how you might think about this.
Upvotes: 1
Reputation: 5606
It seems that you are confusing the mutability of the variable hm
with the mutability of the map held by the variable, which are different. val hm
means that you cannot assign hm
to any other HashMap, not that the HashMap cannot be modified (as @nmat and @puhlen have explained).
Upvotes: 10
Reputation: 8529
java.util.HashMap
is not immutable. This has nothing to do with it coming from java or scala, but the properties of the class itself. You could use a scala.collection.mutable.HashMap
and see the same behavior. Likewise, an immutable HashMap implementation written in java would not be mutable if you used it in scala.
Upvotes: 1
Reputation: 7591
java.util.HashMap
is mutable. The Scala immutable counterpart is scala.collection.immutable.HashMap:
val myMap = scala.collection.immutable.HashMap[Int, String]()
myMap + ((1,"a"), (2, "b")) //new instance of Map(1 -> a, 2 -> b)
println(myMap) //Map()
Upvotes: 1