If you look at hashCode
implementation of a mutable HashSet
in scala, you'll find out that it hashes all its internal elements. My scala version ends up in MurmurHash3.unorderedHash(...)
call when hashing. Probably can be different at others.
If you ask why? I guess that's because Set("Abc", "def") != Set("Abc", "def", "ghi")
and also to be aligned with immutable HashSet
implementation. It makes perfect sense and I have no idea why you would do otherwise.
Update
Some additional explanation to answer author's comments
hashCode
is all about equality, not about the same object. The rule is that if two objects are equal, then they should return the same hashCode
. If they are not - they better return different (I say better, because its still possible they return the same by collision). This is true for all objects.
Consider this code:
import scala.collection.mutable.Set
val s1 = Set(1)
val superSet = Set(s1)
println(superSet.contains(s1)) // prints true
println(superSet.contains(Set(1)) // still prints true
Notice that both prints true, even though s1
and Set(1)
are two different objects in memory. This is because their equals
and hashCode
returns the same
Now there is a small problem with this implementation:
import scala.collection.mutable.Set
val superMap = scala.collection.mutable.Map.empty[Set[String], Boolean]
superMap += (set -> true)
println(superMap.contains(set)) // prints true
set += "ghi"
println(superMap.contains(set)) // prints false
println(superMap.contains(Set("Abc", "def"))) // still prints false
The second println
prints false
. This is because Map
can no longer find the key, because key has changed its hashCode
, but Map
still remembers the old one. The third println
still fails the check, because even though the contains hashCode
in Map
and Set("Abc", "def").hashCode
are the same, the sets fail the equality check afterwards.
This is a well-known problem and there is no good solution, so it is recommended to never use mutable objects as the keys to HashMap
. In general you should not use mutable objects for any structure where hashCode
-check and then equality
-check is applied. The same thing holds for HashSet