当我从Eclipse IDE生成equals和hashCode方法时,我遇到了Hash Collision问题。
我打算将Scala API
case classes
用于同一目的,因为它会自动创建equals
和hashcode
。
Scala生成的方法是否足以处理Hash Collision问题?
在使用案例类时,任何人都遇到了哈希碰撞问题吗?
答案 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。