What is the difference between `##` and `hashCode`?
What is the difference between methods ## and hashCode?
They seem to be outputting the same values no matter which class or hashCode overloading I use. Google doesn't help, either, as it cannot find symbol ##.
"Subclasses" of AnyVal do not behave properly from a hashing perspective:
scala> 1.0.hashCode res14: Int = 1072693248
Of course this is boxed to a call to:
scala> new java.lang.Double(1.0).hashCode res16: Int = 1072693248
We might prefer it to be:
scala> new java.lang.Double(1.0).## res17: Int = 1 scala> 1.0.## res15: Int = 1
We should expect this given that the int 1 is also the double 1. Of course this issue does not arise in Java. Without it, we'd have this problem:
Set(1.0) contains 1 //compiles but is false
scala> Set(1.0) contains 1 res21: Boolean = true
## was introduced because hashCode is not consistent with the == operator in Scala. If a == b then a.## == b.## regardless of the type of a and b (if custom hashCode implementations are correct). The same is not true for hashCode as can be seen in the examples given by other posters.
Just want to add to the answers of other posters that although the ## method strives to keep the contract between equality and hash codes, it is apparently not good enough in some cases, like when you are comparing doubles and longs (scala 2.10.2):
> import java.lang._ import java.lang._ > val lng = Integer.MAX_VALUE.toLong + 1 lng: Long = 2147483648 > val dbl = Integer.MAX_VALUE.toDouble + 1 dbl: Double = 2.147483648E9 > lng == dbl res65: Boolean = true > lng.## == dbl.## res66: Boolean = false > (lng.##, lng.hashCode) res67: (Int, Int) = (-2147483647,-2147483648) > (dbl.##, dbl.hashCode) res68: (Int, Int) = (-2147483648,1105199104)