1

很抱歉将两个问题合二为一,它们是相关的。

HashCodes 代表HashSets 等。据我了解,它们必须是唯一的,不能更改,并且将对象的任何配置表示为单个数字。

我的第一个问题是,对于我的对象,包含两个 Int16a和,我认为返回类似于n 是一个大数的东西b是否安全?GetHashCodea * n + bMath.Pow(2, 16)

GetHashCode似乎不灵活地专门返回 Int32 类型。

32bits可以存储,例如两个Int16,一个unicode字符或16个N、S、E、W罗盘方向,数量不多,即使是一些小的节点图也可能太多了。这是否代表 C# Hash 集合的限制?

4

2 回答 2

7

据我了解,它们必须是独一无二的

没有。对于大多数类型来说,它们不可能是唯一的,它们可以有超过 2 32 个可能的值。理想情况下,如果两个对象具有相同的哈希码,那么它们不太可能相等 - 但您永远不应该假设它们相等的。重要的一点是,如果它们有不同的哈希码,它们肯定是不相等的。

我的第一个问题是,对于包含两个 Int16 a 和 b 的对象,我的 GetHashCode 返回类似 a * n + b 之类的东西是否安全,其中 n 是一个大数,我想也许是 Math.Pow(2, 16) .

如果它只包含两个Int16值,那么使用起来最简单:

return (a << 16) | (ushort) b;

然后该值是唯一的。万岁!

GetHashCode显得不灵活地返回具体类型Int32

是的。诸如Dictionary和之类的类型HashSet需要能够使用固定大小,以便他们可以使用它来将值放入存储桶中。

32bits可以存储,例如两个Int16,一个unicode字符或16个N、S、E、W罗盘方向,数量不多,即使是一些小的节点图也可能太多了。这是否代表 C# Hash 集合的限制?

如果这一个限制,那将是 .NET 限制而不是 C# 限制 - 但不,这只是对哈希码的含义的误解。

Eric Lippert 有一篇出色的(显然)博客文章GetHashCode,您应该阅读它以获取更多信息。

于 2012-04-14T18:14:05.133 回答
1

GetHashCode对于对象的每个实例来说不是(也不能是)唯一的。以Int64为例;即使散列函数是完美分布的,也会有240 亿个s 散列到每个值,因为正如你提到的,散列码只是一个. Int64Int32

然而,这并不是对使用哈希码的集合的限制;它们只是将桶用于哈希到相同值的元素。因此,不能保证对哈希表的查找是单个操作。获取正确的存储桶是一个操作,但该存储桶中可能有多个项目。

于 2012-04-14T18:14:51.577 回答