Scala案例类和Hash Collision

时间:2016-02-09 04:17:49

标签: scala apache-spark

当我从Eclipse IDE生成equals和hashCode方法时,我遇到了Hash Collision问题。

我打算将Scala API case classes用于同一目的,因为它会自动创建equalshashcode

Scala生成的方法是否足以处理Hash Collision问题?

在使用案例类时,任何人都遇到了哈希碰撞问题吗?

2 个答案:

答案 0 :(得分:6)

请注意:如果您的数据比哈希代码有更多位,则哈希冲突不可避免,原因很简单,因为有可能的值比可能的哈希码更多。

但是,scala case类哈希代码使用MurmurHash3哈希算法,这为非加密哈希函数提供了非常好的哈希值分布。因此案例类的哈希冲突应该相对罕见。您仍然需要在代码中正确处理它们!

另一句话:您的代码必须正确处理哈希码冲突。但它们很少具有良好的散列函数。因此,如果你真的想要彻底,你应该进行测试,你有意拥有多个具有相同哈希码的案例类。

答案 1 :(得分:2)

请注意,Scala案例类根据定义仅依赖于其参数值的对象,这意味着如果构造具有相同参数的两个实例,则将获得相同的哈希值和等号。

scala> case class Example(number: Int, label: String)
defined class Example

scala> val e1 = Example(42, "test")
e1: Example = Example(42,test)

scala> val e2 = Example(42, "test")
e2: Example = Example(42,test)

scala> e1 == e2
res0: Boolean = true

scala> e1.hashCode
res1: Int = 1424814261

scala> e2.hashCode
res2: Int = 1424814261

scala> class OtherExample(val number: Int, val label: String)
defined class OtherExample

scala> val o1 = new OtherExample(42, "test")
o1: OtherExample = OtherExample@6f077e50

scala> val o2 = new OtherExample(42, "test")
o2: OtherExample = OtherExample@1b0c366b

scala> o1 == o2
res3: Boolean = false

scala> o1.hashCode
res4: Int = 1862762064

scala> o2.hashCode
res5: Int = 453785195

因此,您必须问自己有关您打算拥有的参数的确切分布。如果你想区分具有相同参数的实例,可能常规类是更好的选择 - 你仍然会得到一个自动生成的equals和hashCode。