给定两个不同的字符串,总是这样s.GetHashCode() != s1.GetHashCode()
吗?
不同整数的数量是否小于不同字符串的数量?
不。就像一个简单的思想实验:有多少个字符串(提示:比 2 32多得多,因此可以有多少个唯一的哈希码(提示:2 32。看到问题了吗?)
只要返回两个对象相等,哈希码就必须相等。Equals
此外,每当两个哈希码不相等时,对象本身就不可能相等。没有进一步的要求,但它们应该分布良好,以便哈希表能够很好地执行。所以基本上是:
请注意省略了相应的 ⇐ 变体。这不是等价的,只有两个含义。
引用文档:
哈希函数必须具有以下属性:
如果两个对象比较相等,则每个对象的 GetHashCode 方法必须返回相同的值。但是,如果两个对象比较不相等,则两个对象的 GetHashCode 方法不必返回不同的值。
只要确定对象的 Equals 方法的返回值的对象状态没有修改,对象的 GetHashCode 方法就必须始终返回相同的哈希码。请注意,这仅适用于应用程序的当前执行,并且如果再次运行应用程序,则可以返回不同的哈希码。
为了获得最佳性能,散列函数必须为所有输入生成随机分布。
要添加到@Joey 的声明中,您主要是能让哈希码始终不相等。
有 2^32 个可能的哈希码,但输入字符串是无限的。
哈希冲突保证发生在足够的 (2^32 + 1) 输入值。
事实上,由于生日问题,哈希冲突比人们想象的要普遍得多。当我不久前为使用 64 位哈希码的系统进行数学计算时(它具有比 32 位哈希码更多的可能哈希值,而不是天真地认为的两倍),具有 1 亿个输入值,这是非常可能会有至少 1 次哈希冲突。我认为概率在 1% 左右。
据我所知Object.GetHashCode()
,没有在对象上提供哈希函数(所以我认为 Joey 的考虑在这种情况下是不正确的),它只返回一个由 CLR 分配给对象的唯一索引,当对象被创建和释放时垃圾收集。
所以你不能在给定的时刻有一个哈希码重复(在同一个 AppDomain 中),但你可以有一个重复的时间(在应用程序执行期间可能会多次分配相同的索引)。
这里也讨论了这个问题: Object.GetHashCode() 的默认实现