我已查看this维基百科页面,但我仍然不明白。有人可以帮助我笨拙的头脑理解散列,散列表/散列映射和散列函数的概念吗?一些例子确实会有所帮助。
答案 0 :(得分:20)
维基百科的文章将提供大量技术信息,但哈希的简单视图如下所示。
想象一下,有一个神奇的功能可以为任何对象提供一个数字。给定相同的对象,它总是返回相同的数字。
现在您可以快速测试两个对象是否相同:询问此函数的数字并进行比较。如果它们不同,那么它们就不一样了。
但如果他们有相同的号码怎么办?两个不同的对象可以有相同的数字吗?
是的,在大多数情况下都可以这样做。假设该函数只能给出介于1..10之间的数字,并且有100个不同的对象。当然,一些不同的对象必须具有相同的数字。这就是所谓的“碰撞”。 “碰撞”使我们的快速相等测试不那么有用,所以我们尽可能地减少它的发生。一个好的魔法功能是试图最小化“碰撞”的数量。
那么你还可以用这个号码做什么呢?好吧,你可以用它来索引一个数组。给定一个对象,你可以将它放在由这个神奇函数中的数字给出的索引处。这个数组本质上是一个哈希表;这个神奇的函数是一个哈希函数。
答案 1 :(得分:2)
哈希函数是一种创建任意大量数据的紧凑表示的方法。在带有hashcode方法的java中,这意味着以某种方式描述int(4字节)中对象的状态(无论多大)。并且通常写得相当快,如下所述。
为了简化哈希表/哈希映射,哈希码用作廉价等价的一种。取两个对象a和b类型Foo让我们说出a.equals(b)是否需要500 ms,其中计算(有效)哈希码只需要10ms。因此,如果我们想知道是否a.equals(b)而不是直接首先执行此操作,我们将查看哈希码并询问a.hashCode()== b.hashCode()。请注意,在我们的示例中,这只需要20毫秒。
由于哈希码的API定义,我们知道如果 a的哈希码不等于b,则a.equals(b)永远不应该为真。所以在上面的测试中,如果我们看到哈希码是不相等的,然后我们永远不需要做更长的.equals()测试,这就是为什么你应该总是覆盖hashCode并且一起等于。
您可能还会看到有关编写“好”或“分布均匀”哈希码的参考资料。这与前面关于hashcode和equals的陈述的逆是不正确的事实有关。更具体地说, a.hashCode()== b.hashCode()并不一定意味着a.equals(b)所以好的哈希码的想法就是减少a.hashCode()的可能性=当a.equals(b)为假时,= b.hashCode()。您可能已经看到这被称为哈希函数的冲突。
返回hashmaps / tables。这些基于键/值对。因此,当您添加或检索值时,您将提供密钥。所以地图要做的第一件事就是寻找密钥,这意味着要找到.equals()所提供的密钥。但正如我们上面讨论的那样.equals()可能会非常慢,这意味着通过首先检查哈希码可以大大加快比较。由于当哈希码分布均匀时,你应该知道x是绝对的!= y。
现在除了比较hashmaps / tables之外,实际上使用哈希码来组织数据的内部存储,但是我认为这超出了你现在想要理解的范围。
答案 2 :(得分:1)
This book(和supporting video lectures)提供了一些有关算法和数据结构的精彩解释。有一些关于哈希函数的讲座(1,2)。我推荐这个。
另外,只有FYI,不正确,如{ {3}}在评论中。hashCode()
,在Object
类的实例上调用会在内存中返回此特定实例的地址。
答案 3 :(得分:0)
散列表基本上是一种在数组中存储任何内容并将其检索到与通过索引在数组中查找内容一样快的方式,而不会浪费太多空间。
散列函数的作用是(在此上下文中)根据对象的内容计算将存储对象的数组索引。这意味着,它必须始终为同一对象返回相同的结果,并且应尽可能地为不同的对象返回不同的结果。当两个不同的对象具有相同的散列时,它被称为“碰撞”,你必须特别处理这些情况,这会使整个事情变慢。
答案 4 :(得分:0)
将键映射到散列表的索引称为散列函数。 散列函数包含两部分
哈希代码映射:它将键转换为任意范围的整数。
压缩映射:它将这些整数转换(带入)哈希表的键范围。
答案 5 :(得分:0)
散列函数:如果将同一个对象传递给此函数任何次数,无论是文本,二进制还是数字,总是会得到相同的输出。对于哈希表,使用整数返回哈希函数。
以上功能是调用哈希。
哈希表:以恒定时间或O(1)返回搜索结果的计算机科学的奇迹数据结构。它基于上述散列概念。 因此,它比链表,二进制搜索树等具有更好的访问时间。为什么接近O(1):它在内部使用数组作为基础结构来存储对象,因为数组具有恒定的访问时间,所以哈希表也是如此。
[基本内部]: 因此,它在内部使用固定大小的数组,当您插入(Key,Value)对时,它会计算键的散列并使用此散列值作为索引来存储数组中的(Key,Value)对。接下来,当您使用相同的键搜索对象时,它再次使用键的哈希作为索引来搜索数组中的键。 现在,两个对象可以具有相同的哈希值,因此,在哈希表中插入这些对象时会发生冲突。有两种方法可以解决冲突。您可以参考此link进行有关此主题的详细讨论。
答案 6 :(得分:0)
哈希函数:-哈希函数采用一组字符(称为键)并将其映射到一定长度的值(称为哈希值或哈希)。哈希值代表原始字符串,但通常小于原始值。 哈希用于索引和定位数据库中的项目,因为查找较短的哈希值比查找较长的字符串更容易。哈希也用于加密。此术语也称为哈希算法或消息摘要功能。
HASH MAP:-HashMap是一个收集类,旨在将元素存储为键值对。地图提供了一种基于另一项价值查找事物的方法。
一种查找表,旨在有效地存储在字母或数字序列中可能存在较大差异的非连续键(帐号,部件号等)。
哈希表:-哈希表是通过一种算法创建的,该算法将密钥存储到包含键值对的哈希存储桶中。由于不同的键可能会散列到同一存储桶,因此散列表设计的目的是均匀分布散布的键-值对,每个存储桶包含尽可能少的键-值对。查找项目时,会对其哈希进行哈希处理以找到合适的存储桶,然后将存储桶进行比较以找到正确的键值对。
答案 7 :(得分:-1)
HashCode()
函数返回一个整数值,HashMap
使用该函数来查找正确的存储桶。