自定义类型 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 [重复]的主要内容,如果未能解决你的问题,请参考以下文章