代码之家  ›  专栏  ›  技术社区  ›  Dimitri C.

如果我从来没有使用过哈希集,我应该仍然实现GetHashCode吗?

c#
  •  5
  • Dimitri C.  · 技术社区  · 16 年前

    我从不需要将对象存储在哈希表中。原因有两方面:

    • 提出一个好的哈希函数是困难的,而且容易出错。
    • AVL树几乎总是足够快,它只需要一个严格的顺序谓词,这样更容易实现。

    另一方面,equals()操作是一个非常常用的函数。

    因此,我想知道在实现equals函数(我经常需要)时是否需要实现gethashcode(这是我不需要的)?

    7 回复  |  直到 13 年前
        1
  •  13
  •   Andrey    16 年前

    我的建议-如果你不想使用它,请覆盖它,然后 throw new NotImplementedException(); 这样你就能知道你在哪里需要它。

        2
  •  5
  •   Community Mohan Dere    9 年前

    我认为,如果您认为实现严格顺序谓词比哈希函数更容易实现,那就大错特错了——它需要处理大量的边缘情况(空值、类层次结构)。和哈希函数 aren't that difficult ,真的。

        3
  •  4
  •   Brian Gideon    13 年前

    AVL树将比哈希表慢得多。如果你只处理一些项目,那么这不会是一个大问题。哈希表有o(1)个插入、删除和搜索,而avl树有o(log(n))个操作。

    我会继续超越 GetHashCode 和 Equals 有两个原因。

    • 通过使用一个简单的XOR实现来获得一个合适的分布并不是那么困难。 一
    • 如果您的类是公共API的一部分,那么其他人可能希望将它们存储在哈希表中。

    另外,我也不得不质疑BST的选择。AVL树有点过时了。还有其他更现代的BST更容易实现和工作(有时更好)。如果您确实需要维护排序的数据结构,那么考虑这些替代方案。


    一 XOR策略有一个微妙的关联性问题,在某些情况下会导致冲突,因为 a^b = b^a . 有个解决方案 Effective Java 这已经获得了类似邪教的认可,而且实施起来也相当简单。

        4
  •  3
  •   thecoop    16 年前

    如果你使用 Dictionary 或 SortedList 和重写 Equals ,您需要有一个哈希函数,否则它们将中断。 等于 也会在bcl中的所有位置使用,如果其他人使用您的对象,他们会期望 GetHashCode 理智地行为。

    注意,哈希函数不必那么复杂。一个基本的版本是获取用于相等的任何成员变量的散列值,用一个单独的互质数相乘,然后将它们XOR在一起。

        5
  •  2
  •   sfussenegger    16 年前

    你不需要实现它。如果您编写自己的equals()方法,我建议使用一些不会破坏哈希集的getHashCode实现。例如,您可以返回一个静态值(通常为42)。哈希集的性能将显著降低,但至少它仍然可以工作——您永远不会知道将来谁会使用/编辑/维护您的代码。(编辑:如果在散列结构中使用此类,则可能需要记录警告,以便及早发现性能问题)

    编辑:不要只使用XOR来组合属性的哈希代码。

    其他人已经说过,您可以简单地组合所有属性的哈希代码。不过,我建议不要只使用XOR,而是使用乘法结果。如果两个值相等(例如 0xA ^ 0xA == 0x0 )这可以很容易地改进使用 0xA * 0xA , 0xA * 31 + 0xA 或 0xA ^ (0xA * 31) .

    不过,我的答案是,任何哈希函数都比不符合equals的函数好——即使它只返回一个静态值。只需选择用于相等的任何属性子集(从无到全部),并将结果放在一起。在选择哈希代码的属性时,最好选择那些组合非常独特的小子集(例如firstname、lastname、birthday-无需添加整个地址)。

        6
  •  1
  •   Tormod Fjeldskår    16 年前

    提出一个 充足的 哈希函数是 不 很难。通常,一个简单的 GetHashCode() 在所有字段中就足够了。

        7
  •  1
  •   Craig Suchanec    16 年前

    如果重写equals,则应重写msdn中的gethashcode():“建议重写equals的任何类也重写system.object.gethashcode。” http://msdn.microsoft.com/en-us/library/ms173147.aspx

    这两个函数应该匹配,如果两个对象相等,它们应该具有相同的哈希值。这并不意味着如果两个对象具有相同的哈希值,那么它们应该相等。您不需要过于复杂的哈希算法,但它应该尝试在整型空间中很好地分布。