GetHashCode()值对于字符串对象是唯一的还是不唯一的?

时间:2012-09-17 18:21:44

标签: .net string unique hashcode

有人可以帮我理解GetHashCode()方法对字符串值的作用吗?

MSDN我发现:

如果两个字符串对象相等,则GetHashCode方法返回相同的值。但是,每个唯一字符串值都没有唯一的哈希码值。不同的字符串可以返回相同的哈希码。

因此,不同的字符串可以返回相同的哈希码,哈希码对于字符串不是唯一的。它会导致程序核心中的错误吗?

5 个答案:

答案 0 :(得分:3)

如果您认为匹配的哈希码表示匹配的字符串,则可能导致错误。通常,您使用哈希代码将字符串排序到存储桶中以便快速搜索和选择。如果您检测到两个字符串具有匹配的哈希码,则通常会比较字符串本身是否相等。

如果这不能回答你的问题,那么我不明白这个问题。

答案 1 :(得分:3)

好吧,如果您的算法依赖每个字符串来获得唯一的哈希值,这可能会导致错误。

例如,哈希映射(.NET中的字典)可能在冲突时失败(即两个具有相同哈希的对象不相等),或者如果它处理冲突则不会,这取决于确切的实现。在这种情况下失败意味着:如果向地图添加一个新对象,并且地图中已有一个对象具有与新对象相同的散列值,则新对象将覆盖旧对象而不是仅添加。据我所知,.NET中的Dictionary类可以处理冲突。

如果您需要更具体的建议,您需要提出一个更具体的问题:您想要存档的内容,您打算如何进行存档等。

作为旁注:字符串的哈希值通常不是唯一的,因为哈希值的大小是有限的,而字符串的长度则不是。可以这样想:假设哈希函数是MD5(它不是.Net中的默认值),你有一个由十六进制字符组成的字符串(0-9A-Z),字符串长度为200个字符:有字符串的200 ^ 16个可能值,但其哈希值只有32 ^ 16个可能的值。

答案 2 :(得分:2)

  

因此,不同的字符串可以返回相同的哈希码,哈希码对于字符串不是唯一的。它会导致程序核心中的错误吗?

如果哈希值按预期使用,则不应导致错误。由GetHashCode()返回的哈希不是为了提供唯一的哈希值 - 这是不可能的,因为只有大约40亿个可能的哈希码(因为该方法返回Int32),但是无限可能字符串。

哈希意味着提供少数集合,而不是没有冲突。因此,您应该永远假设散列是基于值的唯一表示。你得到的唯一保证是两个不同字符串的两个不同的哈希码意味着字符串不相等,因为两个相等的值应该总是产生相同的哈希值。但是,两个相等的哈希码并不一定意味着两个字符串值相等。

答案 3 :(得分:2)

Hashcode用于加速搜索Hash集合中的对象。在内部,它们将对象存储在许多桶中。被保持的对象基于其哈希码被分成桶。所以当你打电话给例如

var value = Dictionary["someKey"]

字典而不是在所有内部存储桶中搜索直接进入应该包含该键下的值的存储桶。而字典只在那个桶中搜索。

也许这不是它的实现方式,但应该或多或少。 因此,在这种情况下,字典中的不同键具有相同的哈希码并不重要。这只意味着该密钥下的值最终会在同一个桶中。

答案 4 :(得分:2)

实际上,文档对方法所做的保证非常准确。哈希码遵循以下两条规则(a == b引用a.Equals(b)#a出于可读性原因引用a.GetHashCode()

  • 如果a == b然后#a == #b
  • 如果#a != #b然后a != b

请注意,这不是 Equals与匹配哈希之间的等价关系。如果您依赖的不仅如此,那么您的代码显然存在错误。 GetHashCode旨在将对象用作字典中的键,以便从对象到数字的快速映射,但它不需要是可逆的。如果你查看字符串,你可以很容易地看到可能的字符串数量快速超过可能的哈希码数量,所以你可以自己回答这个问题。你已经超过2个 32 可能的字符串,而且已经超过两个字符了。