我有以下代码来生成对象的哈希:
public int GetHashCode(MyType obj)
{
return (obj.Prop1.GetHashCode() + obj.Prop2.GetHashCode() + obj.Prop3.GetHashCode()).GetHashCode();
}
即。我添加了所有属性的哈希码,然后采用哈希值。
在审查中,一位同事建议这将过于频繁地发生碰撞。我不确定这是真的,因为:
谁是对的?
如果答案是针对特定语言的,那么它就在C#中。
答案 0 :(得分:6)
是
假设Prop1,Prop2等属于int
类型。通常只使用较低范围的整数。您的总和方法将比必要时更频繁地发生碰撞。
7
的HasCode是7,在自己散列int
时非常有意义。但是使用代码时,元组<7, 3>
,<3, 7>
和<8, 2>
都将具有相同的哈希值。与简单的XOR相同而不是加法。
常见的方法是添加一些(素数)和移位:
public int GetHashCode(MyType obj)
{
int hash = 0;
unchecked
{
hash += 19 * obj.Prop1.GetHashCode();
hash += 31 * obj.Prop2.GetHashCode();
hash += 37 * obj.Prop3.GetHashCode();
}
return hash;
}
数字19,31,37并不太重要。如果您愿意,可以使用OR或XOR代替+
。
答案 1 :(得分:2)
XORing会更好:
public int GetHashCode(MyType obj)
{
return obj.Prop1.GetHashCode() ^
obj.Prop2.GetHashCode() ^
obj.Prop3.GetHashCode();
}
答案 2 :(得分:0)
您可以使用修改过的FNV HashCode生成器,一个非常类似的问题已被回答(由我) here