【问题标题】:overide GetHashCode when input is two Int16当输入为两个 Int16 时覆盖 GetHashCode
【发布时间】:2012-04-01 15:10:56
【问题描述】:

User.ID 和 Group.ID 都是 Int16 且不可变的,我想生成最佳的 HashCode。

这就是平等

    public override bool Equals(Object obj)
    {
        //Check for null and compare run-time types.
        if (obj == null || GetType() != obj.GetType()) return false;
        UserGroup item = (UserGroup)obj;
        return (User.ID == item.User.ID && Group.ID == item.Group.ID);
    }

什么是最佳的 GetHashCode。现在我正在使用以下内容,但这只是因为我将其视为示例。 Object 的主要用途是在 HashSet 中,HashSet 有很多 .Select(x => x.User.ID = y) 或 .Select(x => x.Group.ID = y)。

  public override int GetHashCode() { return (int)User.ID ^ (int)Group.ID; }

【问题讨论】:

  • 请写GetType() != obj.GetType(),而不是!(obj is UserGroup)

标签: .net hashcode


【解决方案1】:

永远不要错过生成完美哈希的机会。两个 16 位短裤适合 32 位 int:

    public override int GetHashCode() {
        return (User.ID & 0xffff) + (Group.ID << 16);
    }

表达式的第一部分隔离了低 16 位,& 运算符是必要的,以使其对负值正常工作,因此仅使用位 0 到 15。第二部分将 Group.ID 的 16 位移动到位位置 16 到 31。将它们相加将两组 16 位组合成一个 32 位数字。

【讨论】:

  • 也不完全理解这个答案,但在使用几个值进行测试时,它确实产生了独特的结果。那些使用 XOR 的相同值并没有产生唯一的结果,所以我显然是一个更好的哈希值。我发布了另一个问题,将两个 32 打包成一个 64,然后提取您是否想快速回答。
  • 这不仅仅是一个更好的散列,它是一个完美散列:)
【解决方案2】:

好吧,如果您想要良好的散列分布,实际上两者都不是首选(仅举一个例子:在您的实现中,User.ID = 10, Group.ID = 5 将散列到与 User.ID = 5, Group.ID 相同的值。 ID = 10)。当然,它是可用的,但请看看 the master 对此有何评论。

【讨论】:

  • 我看到了这一点并相信 Keets 是正确的答案,但老实说我不明白。
  • 嗯,(非常简化的)要点是您希望避免不同的输入来生成相同的哈希码(“哈希冲突”),因为这样会影响任何基于哈希的算法或类的性能将开始从 O(1) 向 O(n) 退化。 Hans 的回答非常准确,因为在您的用例中,可以生成一个哈希码,保证每个唯一输入组合都是唯一的(这是一个“完美哈希”):您有两个 16 位整数和哈希码是 32 位的,因此它可以容纳您输入的所有可能组合。
猜你喜欢
  • 1970-01-01
  • 2012-07-13
  • 1970-01-01
  • 2011-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-11
  • 1970-01-01
相关资源
最近更新 更多