自定义类型 GetHashCode [重复]

Posted

技术标签:

【中文标题】自定义类型 GetHashCode [重复]【英文标题】:Custom type GetHashCode [duplicate] 【发布时间】:2011-06-30 21:46:17 【问题描述】:

可能重复:What is the best algorithm for an overridden System.Object.GetHashCode?

我需要为由三个字符串组成的类型覆盖 GetHashCode 方法。这是我的代码:

protected override int GetHashCode()

    return str1.GetHashCode() + str2.GetHashCode() + str3.GetHashCode();

这种方法实现的安全方式是什么?

【问题讨论】:

【参考方案1】:

最好的方法是避免任何会产生相同哈希码的事情,如果您:

交换了操作数的顺序 有一个大部分为零的值,只是移动非零值

这些帐户的加法(单独)和 XOR 均失败。

这里有一个更好的方法:

public override int GetHashCode()

    unchecked
    
        int result = 37; // prime

        result *= 397; // also prime (see note)
        if (str1 != null)
            result += str1.GetHashCode();

        result *= 397;
        if (str2 != null)
            result += str2.GetHashCode();

        result *= 397;
        if (str2 != null)
            result += str2.GetHashCode();

        return result;
    

您是否在该代码中使用加法或 XOR 有待商榷,我见过使用这两种方法的示例,但没有明确分析哪个更好(即均匀分布)。选择一个并使用它。

397 是ReSharper addin when it generates GetHashCode implementations 使用的默认值,显然被选中是因为它通常会溢出 int 的范围,因此可以更好地混合位。围绕这种特定格式的 GetHashCode 实现有很多理论,但它是最常用的一种。

【讨论】:

【参考方案2】:

我总是使用异或(Xor)而不是加法,因为它不倾向于在任何地方获取数字(比如大值)。所以我会这么说

protected override int GetHashCode()
 return str1.GetHashCode() ^ str2.GetHashCode() ^ str3.GetHashCode(); 

是一个更好的实现。

你也可以尝试改变它,比如

protected override int GetHashCode()

    unchecked
    
        return (str1.GetHashCode() * 1369) ^
               (str2.GetHashCode() * 37) ^ str3.GetHashCode();
    

如果您想确保切换字符串的值会产生不同的结果。有各种各样的方法可用于散列(例如universal hashing),所以如果您正在寻找,只需搜索散列方法即可。

【讨论】:

第二种形式需要用unchecked包围。 好点...我会改变它,谢谢。 (虽然默认不勾选也不一定。) 您不想依赖此代码的任何默认值。

以上是关于自定义类型 GetHashCode [重复]的主要内容,如果未能解决你的问题,请参考以下文章

覆盖 GetHashCode [重复]

Distinct去除集合中的重复项GetHashCode方法没有返回obj.GetHashCode()导致出错

自定义帖子类型 slug 重复

如何自定义模板以不包含某些类型[重复]

自定义条件判断两对象相等Equals的方法

在kotlin的自定义类型arraylist中按id搜索对象[重复]