方法##
和hashCode
之间有什么区别?
无论我使用哪个类或hashCode
重载,它们似乎都在输出相同的值。谷歌也没有帮助,因为它找不到符号##
。
答案 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.##
返回0
而null.hashCode
抛出{{1 }}。
来自scaladoc:
与x.hashCode等效,除了带框的数字类型和null。对于数字,它返回一个与值相等一致的哈希值:如果两个值类型实例的比较结果为true,则##将为每个实例产生相同的哈希值。对于null,返回一个哈希码,其中null.hashCode抛出NullPointerException。