[英]C# GetHashCode Implementation
是
public override int GetHashCode()
{
return Word.GetHashCode();
}
真的一样
public override int GetHashCode()
{
return (int) Word.GetHashCode() * 7;
}
关于独特性?
Word
是String
类型
编辑:我忘了说,哪个更好地在程序中实现,选项1或2?
显然, Word.GetHashCode()
实现中的任何冲突都将导致(int) Word.GetHashCode() * 7
实现中的冲突,因为将相同的数字相乘会产生相同的结果。
一个更有趣的问题是,第一个实现中的非冲突哈希码是否会导致第二个实现中的冲突。 事实证明答案是“否”,因为int
和7
的范围是互质数。 因此,乘法在消除溢出后会产生唯一的映射。
您可以使用两个字节的哈希码运行小型测试,以查看会发生什么:
const int Max = 1<<16;
var count = new int[Max];
for (int i = 0 ; i != Max ; i++) {
count[(i * 7) & (Max-1)]++;
}
var notOne = 0;
for (int i = 0 ; i != Max ; i++) {
if (count[i] != 1) {
notOne++;
}
}
Console.WriteLine("Count of duplicate mappings found: {0}", notOne);
该程序将哈希码值i
映射到7 * i
2 16为模,并验证该范围内的每个数字是否恰好产生一次。
Count of duplicate mappings found: 0
如果将7
替换为偶数,结果将大不相同。 现在,原始集中的多个哈希码将被映射到目标集中的单个哈希码。 如果您记得乘以偶数始终会使最低有效位为零,则可以直观地理解这一点。 因此,根据偶数可以除以2的次数,一些信息会丢失。
哪一个更好?
没有区别。
注意:以上假设您忽略整数溢出。
由于您不是在unchecked
上下文中运行代码,因此后者会在发生溢出的任何时间引发异常,这很可能会发生(哈希范围的6/7会抛出,因此通常均匀分布的哈希代码具有约有6/7的机会抛出异常)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.