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 Luckily:
scala> Set(1.0) contains 1 res21: Boolean = true equals and hashCode for a particular class, I'm not sure how this translates into the best strategy. I am assuming the hashCode implementation should use ##. However, should the equals implementation use hashCode or ##? Here's the answer I provided on another thread which assumes that the equals implementation should use hashCode and the hashCode implementation should use ##. Evaluation and feedback on this would be greatly appreciated. stackoverflow.com/a/56509518/501113## 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.
equals and hashCode for a particular class, I'm not sure how this translates into the best strategy. I am assuming the hashCode implementation should use ##. However, should the equals implementation use hashCode or ##? Here's the answer I provided on another thread which assumes that the equals implementation should use hashCode and the hashCode implementation should use ##. Evaluation and feedback on this would be greatly appreciated. stackoverflow.com/a/56509518/501113Just 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) == and .## == .##In addition to what everyone else said, I'd like to say that ## is null-safe, because null.## returns 0 whereas null.hashCode throws NullPointerException.
From scaladoc:
Equivalent to x.hashCode except for boxed numeric types and null. For numerics, it returns a hash value which is consistent with value equality: if two value type instances compare as true, then ## will produce the same hash value for each of them. For null returns a hashcode where null.hashCode throws a NullPointerException.
1.0 hashCodev1.0 ##v1 hashCodev1 ##— scala-lang.org/api/current/scala/Any.html1.hashCode==1.##, and1.2.hashCode==1.2.##. The only thing that behaves differently is1.0.hashCode!=1.0.##(so##is better suited for comparing numbers).