所以我需要创建一个包含键的字典,这些键是具有自定义Equals()函数的对象。我发现我也需要覆盖GetHashCode()。我听说为了获得最佳性能,您应该使用不会发生冲突的哈希码,但这似乎与直觉相反。我可能误解了它,但似乎使用哈希码的全部意义在于将项目分组到桶中,如果哈希码从不碰撞每个桶,则只有1个项目似乎无法达到目的。
我应该故意让我的哈希码偶尔发生冲突吗?表现很重要。这将是一个字典,可能会增长到数百万个项目,我将经常进行查找。
答案 0 :(得分:2)
哈希代码的目标是为您提供数组的索引,每个数组都是一个可能包含零个,一个或多个项目的存储桶。然后,查找的性能取决于存储桶中的元素数量。越少越好,因为一旦你进入桶中,它就是O(n)搜索(其中n是桶中元素的数量)。因此,如果哈希码尽可能地防止冲突,那么它是理想的,允许尽可能多的O(1)时间。
答案 1 :(得分:1)
字典将数据存储在存储桶中,但每个哈希码没有一个存储桶。存储桶的数量取决于容量。根据哈希码的模数和桶的数量将值放入存储桶中。
假设您有一个GetHashCode()
方法可以为五个对象生成这些哈希码:
925
10641
14316
17213
28624
应散布哈希码。所以这些看起来很分散吧?如果我们有7个桶,那么我们最终会计算每个桶的模数:
1
1
1
0
1
所以我们最终得到了桶:
0 - 1 item
1 - 4 items
2 - 0 items
3 - 0 items
4 - 0 items
5 - 0 items
6 - 0 items
哎呀,现在不太好了。
这不是数据。这些是实际的哈希码。
这里有一个如何从包含的数据生成哈希码的示例(不是用于上述哈希码的公式,更好的一个)。
答案 2 :(得分:0)
您必须确保以下内容成立:
(GetHashCode(a) != GetHashCode(b)) => !Equals(a, b)
反向含义的含义相同:
Equals(a, b) => (GetHashCode(a) == GetHashCode(b))
除此之外,尽可能少地产生碰撞。碰撞定义为:
(GetHashCode(a) == GetHashCode(b)) && !Equals(a, b)
碰撞不会影响正确性,但会影响性能。 GetHashCode
始终返回零将是正确的,例如,但速度很慢。