且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

当字典键发生哈希冲突时会发生什么?

更新时间:2022-04-10 00:19:50

哈希冲突由 Dictionary 正确处理 - 只要对象实现GetHashCode()Equals() 正确,将从字典中返回适当的实例.

Hash collisions are correctly handled by Dictionary<> - in that so long as an object implements GetHashCode() and Equals() correctly, the appropriate instance will be returned from the dictionary.

首先,您不应该对 Dictionary<> 的内部工作方式做出任何假设 - 这是一个可能会随着时间而改变的实现细节.话虽如此....

First, you shouldn't make any assumptions about how Dictionary<> works internally - that's an implementation detail that is likely to change over time. Having said that....

您应该关心的是您用于键的类型是否正确实现了 GetHashCode()Equals().基本规则是 GetHashCode() 必须在对象的生命周期内返回相同的值,并且 Equals() 在两个实例表示同一个对象时必须返回 true.除非你覆盖它,Equals() 使用引用相等——这意味着它只有在两个对象实际上是同一个实例时才返回 true.您可以覆盖 Equals() 的工作方式,但是您必须确保相等"的两个对象也产生相同的哈希码.

What you should be concerned with is whether the types you are using for keys implement GetHashCode() and Equals() correctly. The basic rules are that GetHashCode() must return the same value for the lifetime of the object, and that Equals() must return true when two instances represent the same object. Unless you override it, Equals() uses reference equality - which means it only returns true if two objects are actually the same instance. You may override how Equals() works, but then you must ensure that two objects that are 'equal' also produce the same hash code.

从性能的角度来看,您可能还想提供一种 GetHashCode() 的实现,以生成良好的值传播以减少哈希码冲突的频率.哈希码冲突的主要缺点是,它在性能方面将字典简化为列表.每当两个不同的对象实例产生相同的哈希码时,它们就会存储在字典的同一个内部存储桶中.这样做的结果是,必须执行线性扫描,在每个实例上调用 Equals() 直到找到匹配项.

From a performance standpoint, you may also want to provide an implementation of GetHashCode() that generates a good spread of values to reduce the frequency of hashcode collision. The primarily downside of hashcode collisions, is that it reduces the dictionary into a list in terms of performance. Whenever two different object instances yield the same hash code, they are stored in the same internal bucket of the dictionary. The result of this, is that a linear scan must be performed, calling Equals() on each instance until a match is found.