.NET编译器如何能够为HashSet中的任何T构造O(1)查找<t>?

时间:2015-11-20 17:23:03

标签: c# .net data-structures

我不明白编译器如何能够足够聪明地为MyObject构建O(1)查找,我可以将任何放在

public class MyObject
{
    // ... 
}

我理解如何为有限数量的非基元(例如

)做到这一点
public class MyObject
{
    int i { get; set; }
    char c { get; set; }
}

但是,对于MyObject的任何实现,它怎么可能知道如何执行此操作?

2 个答案:

答案 0 :(得分:7)

  1. 获取哈希码
  2. 模块化以生成数组索引。
  3. 看那里。如果项目存在,请查看它是否相等。
  4. 到目前为止,完美的O(1)。如果很多项目最终都具有模数下降到相同索引的哈希码,那么它就会失败。这种情况发生了一些预期和处理,但如果它一直发生,你最终会出现O(n)行为(并且实际上是非常糟糕的不变成本)。

    默认情况下,所有对象都具有基于引用标识的GetHashCode()Equals()(即,它们仅等于它们自己)。覆盖这些更改它所具有的相等概念,因此当您更改GetHashCode()时,您必须始终更改Equals()(所有相等的对象必须具有相同的哈希码)。您还可以使用IEqualityComparer<T>实现来强制使用不同的相等概念,该实现提供了不同的GetHashCode()Equals()

答案 1 :(得分:6)

每个对象都有Hash Code与之关联。有一个方法GetHashCode (在基础object类中定义为虚拟),必须在类中重写,以便HashSet可以正常工作。

  

哈希码是一个数值,用于插入和识别   基于散列的集合中的对象,例如   字典类,Hashtable类或派生类型   来自DictionaryBase类。 GetHashCode方法提供了这个   需要快速检查对象相等性的算法的哈希码。

使用当前的课程,它将无法正常运行(因为GetHashCode未被覆盖)。相等性的比较将在参考而不是实际值的基础上进行。