`##`和`hashCode`有什么区别?

时间:2012-01-30 17:35:43

标签: scala hashcode

方法##hashCode之间有什么区别?

无论我使用哪个类或hashCode重载,它们似乎都在输出相同的值。谷歌也没有帮助,因为它找不到符号##

4 个答案:

答案 0 :(得分:35)

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

答案 1 :(得分:30)

引入了

##,因为hashCode与Scala中的==运算符不一致。如果a == b,则a.## == b.##,无论a和b的类型如何(如果自定义hashCode实现正确)。 hashCode的情况也是如此,正如其他海报给出的例子所示。

答案 2 :(得分:5)

只想添加其他海报的答案,虽然##方法努力保持相等和哈希码之间的契约,但在某些情况下显然不够好,比如当你比较双打和长号时(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)

答案 3 :(得分:1)

除了其他人所说的,我还要说##是null安全的,因为null.##返回0null.hashCode抛出{{1 }}。

来自scaladoc:

与x.hashCode等效,除了带框的数字类型和null。对于数字,它返回一个与值相等一致的哈希值:如果两个值类型实例的比较结果为true,则##将为每个实例产生相同的哈希值。对于null,返回一个哈希码,其中null.hashCode抛出NullPointerException。