【问题标题】:C#: override GetHashCode, what does this code do?C#:覆盖GetHashCode,这段代码有什么作用?
【发布时间】:2011-10-01 21:58:22
【问题描述】:

这是我在Nhibernate 3 Beginners Guide 中找到的用于覆盖GetHashCode 的代码。我不明白为什么它使用结果 * 397。如果 397 只是他用来生成唯一结果的随机数??

我们可以只用GetHashCode 表示名字、中间名和姓氏,然后用 ^ 将它们组合在一起,它也应该生成一个唯一的结果。

public override int GetHashCode()
{
   unchecked
   {
       var result = FirstName.GetHashCode();
       result = (result*397) ^ (MiddleName != null ? MiddleName.GetHashCode() : 0);
       result = (result*397) ^ LastName.GetHashCode();
       return result;
   }
}

【问题讨论】:

  • 请注意,哈希码的目的不是为了唯一。哈希码不能是唯一的,因为它们的数量不够。哈希算法中乘法的目的是为了得到良好的分布

标签: c# nhibernate gethashcode


【解决方案1】:

将中间哈希码乘以作为每个组合的一部分的给定数字将意味着组合的哈希码的顺序不会无关紧要。

如果您只是对三个名称部分进行了排他性或操作,那么“John William James”将给出与“James William John”相同的哈希码。

之所以选择397,是因为它是一个足以导致散列码溢出的素数,这有助于生成散列码的良好分布。

溢出是这段代码必须位于unchecked 块内的原因。

【讨论】:

  • 这是一个很好的解释,但它没有解释为什么选择质数。这样做是为了减少聚类的可能性。
  • 很好的解释,非常感谢。只是好奇,为什么你需要一个大的“质数”数字,而不是任何其他大数字。
  • @feelexit:它减少了聚类。
【解决方案2】:

乘法也基本上是位移位(如果 * 是 2 的幂,则正好位移位),所以它对这里的计算值有影响,但至于为什么正好是 397,这就是这个特殊的哈希算法的编写方式.是的,其他值,确实更复杂的算法经常被用作哈希算法。

这与简单地将 3 个哈希码异或在一起不同,并且会导致更少的“哈希冲突”——其中 2 个(或更多)对象哈希到相同的值(如果在良好的哈希函数中不能避免,则可以将其最小化)

【讨论】:

    猜你喜欢
    • 2011-04-13
    • 1970-01-01
    • 2011-12-31
    • 2011-01-14
    • 1970-01-01
    • 2010-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多