В чем разница между `##` и `hashCode`? - PullRequest
35 голосов
/ 30 января 2012

В чем разница между методами ## и hashCode?

Похоже, они выводят одинаковые значения независимо от того, какой класс или перегрузку hashCode я использую.Google тоже не помогает, так как не может найти символ ##.

Ответы [ 3 ]

36 голосов
/ 30 января 2012

«Подклассы» AnyVal не ведут себя должным образом с точки зрения хеширования:

scala> 1.0.hashCode
res14: Int = 1072693248

Конечно, это связано с звонком на:

scala> new java.lang.Double(1.0).hashCode
res16: Int = 1072693248

Мы могли бы предпочесть, чтобы это было:

scala> new java.lang.Double(1.0).##
res17: Int = 1

scala> 1.0.##
res15: Int = 1

Мы должны ожидать этого, учитывая, что int 1 также является double 1. Конечно, эта проблема не возникает в Java. Без него у нас была бы эта проблема:

Set(1.0) contains 1 //compiles but is false

К счастью:

scala> Set(1.0) contains 1
res21: Boolean = true
31 голосов
/ 31 января 2012

## был введен, потому что hashCode не согласуется с оператором == в Scala.Если a == b, то a.## == b.## независимо от типа a и b (если пользовательские реализации hashCode верны).То же самое не относится к hashCode, как это видно из примеров, приведенных другими авторами.

5 голосов
/ 29 января 2014

Просто хочу добавить к ответам других авторов, что, хотя метод ## стремится сохранить контракт между равенством и хеш-кодами, он, по-видимому, недостаточно хорош в некоторых случаях, например, когда вы сравниваете двойные и длинные (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)
...