hashCode的作用是什么?它独特吗?


129

我注意到getHashCode()WP7中的每个控件,项目都有一个方法,该方法返回一个数字序列。我可以使用该哈希码来识别商品吗?例如,我想识别设备中的图片或歌曲,并检查其位置。如果为特定项目指定的哈希码是唯一的,则可以执行此操作。

您能帮我解释一下hashCode及其getHashCode()用途吗?


我知道hashCode是什么意思,我尝试多次运行我的代码以获取哈希码,并且每次都为相同的项目返回相同的哈希码,而且似乎没有重复,但是我不确定。好吧,如果您想投票,可以的,这是您的意见。仍然感谢您的编辑!
Nghia Nguyen

7
我建议阅读Eric Lippert的GetHashCode指南和规则,尽管它着重于实现HashCodes的规则,而不是使用它们的规则...因为它们“ 设计上仅对一件事有用:将对象放入哈希表”
Brian

Answers:


108

MSDN说

哈希码是一个数值,用于在相等性测试期间标识对象。它也可以用作集合中对象的索引。

GetHashCode方法适用于哈希算法和数据结构(例如哈希表)。

GetHashCode方法的默认实现不能保证不同对象的唯一返回值。此外,.NET Framework不保证GetHashCode方法的默认实现,并且它返回的值在.NET Framework的不同版本之间将相同。因此,不得将此方法的默认实现用作哈希目的的唯一对象标识符。

GetHashCode方法可以被派生类型覆盖。值类型必须重写此方法,以提供适用于该类型的哈希函数并在哈希表中提供有用的分布。为了唯一,哈希码必须基于实例字段或属性的值,而不是静态字段或属性。

在Hashtable对象中用作键的对象还必须重写GetHashCode方法,因为这些对象必须生成自己的哈希码。如果用作键的对象不能提供GetHashCode的有用实现,则可以在构造Hashtable对象时指定哈希码提供程序。在.NET Framework 2.0版之前,哈希码提供程序基于System.Collections.IHashCodeProvider接口。从2.0版开始,哈希码提供程序基于System.Collections.IEqualityComparer接口。

基本上,存在哈希码以使哈希表成为可能。
保证两个相等的对象具有相等的哈希码。保证
两个不相等的对象具有相等的哈希码(称为冲突)。


3
MSDN的报价现在已过期。现在,MSDN对于哈希码不是唯一的不那么明确。
user34660

248

了解了所有内容之后,我想通过类比写一个希望更简单的解释:

摘要:什么是哈希码?

  • 是指纹 我们可以使用此指纹来识别感兴趣的人。

请阅读以下详细信息:

当我们尝试唯一识别某人时,请考虑一个哈希码

我是一名侦探,正在寻找犯罪分子。让我们称他为克鲁尔先生。(当我还是个孩子的时候,他是一个臭名昭著的杀人犯–他闯入一所被绑架的房子,谋杀了一个可怜的女孩,丢下了她的尸体,但他仍然处于松散状态-但这是另一回事。)克鲁尔先生具有某些独特的特征,我可以用来在人海中独特地识别他。我们在澳大利亚有2500万人。克鲁尔先生就是其中之一。我们怎么能找到他?

识别残酷先生的坏方法

显然,克鲁尔先生是蓝眼睛的。这没有太大帮助,因为澳大利亚几乎一半的人口也有蓝眼睛。

识别克鲁尔先生的好方法

我还能使用什么?我知道:我会使用指纹!

优点

  • 两个人要拥有相同的指纹确实非常困难(不是不可能,但极不可能)。
  • 克鲁尔先生的指纹永远不会改变。
  • 克鲁尔先生整个生命的每一部分:(在理想情况下)必须在他的指纹中反映出他的长相,头发颜色,性格,饮食习惯等,如果他有一个兄弟(他非常相似但不相同),那么两者应该不同的指纹。我之所以说“应该”,是因为我们不能100%保证这个世界上的两个人会有不同的指纹。
  • 但是,我们始终可以保证,克鲁尔先生将始终拥有相同的指纹-并且他的指纹永远不会改变。

上述特征通常构成良好的哈希函数。

那么“碰撞”有什么用呢?

因此,想象一下,如果我获得了领先,并且找到了匹配克鲁尔先生指纹的人。这是否意味着我找到了克鲁尔先生?

........也许!我必须仔细看看。如果我使用的是SHA256(哈希函数),而我正在一个只有5个人的小镇上看-那么我很有可能找到他!但是,如果我使用MD5(另一种著名的哈希函数)并在拥有+ 2 ^ 1000个人的城镇中检查指纹,那么两个完全不同的人可能拥有相同的指纹是一个相当好的可能性。

那么,这一切的好处是什么?

哈希码的唯一真正好处是,如果您想将某些东西放入哈希表中-并且希望使用哈希表快速查找对象-那就是哈希码的所在。它们使您可以真正在哈希表中查找内容很快。这是一种可大幅提高性能的黑客工具,但准确性却有所降低。

因此,让我们想象一下,我们有一个充满了人们的哈希表-澳大利亚有2500万嫌疑犯。克鲁尔先生在那儿某处.....我们怎么能很快找到他?我们需要对它们全部进行排序:找到潜在的匹配项,或者以其他方式宣判无罪的嫌疑人。您不想考虑每个人的独特特征,因为这将花费太多时间。您将使用什么呢?您将使用哈希码!哈希码可以告诉您两个人是否不同。无论Joe Bloggs是否不是Cruel先生。如果印刷品不符,那您肯定不是克鲁尔先生。但是,如果指纹确实匹配然后根据您使用的哈希函数,找到您的男人的机会已经相当不错了。但这不是100%。您可以确定的唯一方法是进一步调查:(i)他/她是否有机会/动机,(ii)证人等。

当您使用计算机时,如果两个对象具有相同的哈希码值,则再次需要进一步调查它们是否真正相等。例如,您必须检查对象是否具有相同的高度,相同的重量等,是否整数相同,或者customer_id是否匹配,然后得出结论是否相同。这通常可以通过实现IComparer或IEquality接口来完成。

关键摘要

因此,基本上,哈希码是指纹。

数字指纹-图片属性为“ Pixabay”(免费),可在以下网址使用:https://pixabay.com/en/finger-fingerprint-security-digital-2081169/

  1. 理论上,两个不同的人/对象仍可以具有相同的指纹。或者换句话说。如果您有两个相同的指纹…………那么它们不必都来自同一个人/物体。
  2. Buuuuuut,同一个人/对象将始终返回 相同的指纹
  3. 这意味着,如果两个对象返回不同的哈希码,则可以100%确定这些对象是不同的。

您需要花费3分钟的时间才能解决上述问题。也许读几次直到有道理。我希望这对某人有帮助,因为我花了很多时间才学会了这一切!


1
回复:MSDN文档杀死了我的一些脑细胞 ....驱使我的许多人自杀。只是因为我睡着了才保存了;)
Shwrk 18-3-23

最后,您用星号注释破坏了您的所有很好的解释。
WaldemarGałęzinowski18年

我爱它!主要名称为“克鲁尔先生!
乔·佩德罗·安德拉德·马克斯

作为一名真正的犯罪爱好者,这很可能是我最喜欢的SO答案……。
IfElseTryCatch

11

GetHashCode()用于帮助支持将对象用作哈希表的键。(Java等中也存在类似的东西)。目标是让每个对象都返回不同的哈希码,但这通常不能绝对保证。这是必需的,虽然这两个逻辑上相等的对象返回相同的散列码。

典型的哈希表实现从hashCode值开始,采用模数(因此将值限制在一个范围内),并将其用作“存储桶”数组的索引。


8

它不是WP7独有的-它存在于所有.Net对象中。它确实可以满足您的描述,但我不建议您将其作为应用程序中的唯一标识符,因为不能保证它是唯一的。

Object.GetHashCode方法


4

这来自msdn文章:

https://blogs.msdn.microsoft.com/tomarcher/2006/05/10/are-hash-codes-unique/

“虽然您会听到人们说哈希码会为给定的输入生成唯一值,但事实是,虽然很难实现,但找到两个哈希值都相同的数据输入在技术上是可行的。决定散列算法有效性的因素在于所产生的散列码的长度和被散列数据的复杂性。”

因此,只需使用适合您数据大小的哈希算法,它将具有唯一的哈希码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.