Bunder
Bunder

Reputation: 223

Immutability of Java objects in Scala

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

Answers (4)

Mark Lewis
Mark Lewis

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

Serg M Ten
Serg M Ten

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

puhlen
puhlen

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

nmat
nmat

Reputation: 7591

java.util.HashMapis 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

Related Questions