哈希码和基于哈希的集合(即 HashMap 和 HashSet)之间有什么关系?
What is the relation between hashcode and hash-based collections (i.e. HashMap and HashSet)?
我已阅读here,
An object’s hash code allows algorithms and data structures to put
objects into compartments, just like letter types in a printer’s type
case. The printer puts all “A” types into the compartment for “A”, and
he looks for an “A” only in this one compartment. This simple system
lets him find types much faster than searching in an unsorted drawer.
That’s also the idea of hash-based collections, such as HashMap and HashSet.
但我不明白。这里提到了什么想法? HashMap 或 HashSet 与哈希码有什么关系?
编辑:
以HashSet
为例。
假设它存储 7 个对象(让我们用字母表示它们),它们可以是从 A 到 E 的任何对象。假设它在第 0 个索引位置有 A,B 在第 1 个位置,在第二个位置,A 在第三个位置索引,然后在第四个索引处再次出现 A,然后在第五个索引处出现 D,在第六个索引处出现 E。等等。这是一种存储形式。
hashSet => [A, B, C, A, A, D, E]
然后还有另一种存储形式,其中所有三个 A 都放在一个隔间中,然后 B 在另一个隔间中,C 在另一个隔间中,D 和 E 在另外两个隔间中。
基于hashCode的分类=> [A, A, A], [B], [C], [D], [E]
现在如果我检查 hashSet.contains('A')
,它会直接查看包含 A
的隔间,这是第一个隔间,并为隔间的每个成员计算 A.equals(member-of-compartment)
?
我说得对吗?
HashMap 或 HashSet 就像带隔层的抽屉。这些数据结构使用 hashCode 将对象放在正确的隔间中。
一个非常简单的Strings hashCode(不是Java用的那个,而是现实生活中用的比较多的那个)就是String的第一个字母。这就是很多人用来把东西放在正确的隔间里的方法。
所以无论是HashMap还是HashSet,都是先根据hashCode查找合适的隔间来搜索对象。一旦他们找到了合适的隔间,他们就会从前到后查看以找到合适的物品(但理想情况下,每个隔间中只有很少的物品)
编辑:
您在编辑中使用 HashSet 是正确的。 (如果您将 hashCode 函数实现为始终 return 相同的值,比如零,那么它将像 "hashSet => [A, B, C, A, A, D, E]" 一样工作 - 它会将所有内容放入一个 bucket/compartment)
请注意,HashMap 和 HashSet 在实现方式上几乎没有区别。 HashSet 只是一个 HashMap,它只使用键并使用单个 pre-defined 值来指示键存在于映射中。
Hash-based collection 具有通常称为 桶 的内容。所有具有相同散列码的 object 都进入同一个桶。这与打印机的类型案例示例的想法相同。 hash-based collection 的桶就像打印机的类型盒隔层。
所有 "A" 都进入同一个隔间,就像所有具有相同哈希码的 object 进入同一个桶一样。
打印机根据它是哪个字母来决定哪个隔间,而不考虑类型。这里的"hash code"操作就是类型是哪个字母。
类似地,hash-based collections 需要找到 object 属于哪个桶。他们通过获取 object 的哈希码来做到这一点。
就像打印机只需要在 "A" 隔间中查找所需的特定 "A" 一样,hash-based collection 调用 hashCode()
方法来确定要查找哪个存储桶以查找 object.
打印机仍然需要目视检查隔间中的每个 object 是否有 he/she 需要的东西。同样,一个 hash-based collection 仍然需要找到正确的 object,即使多个 object 在同一个桶中。 hash-based collection 调用 equals
以查看 object 的键是否存在。
我已阅读here,
An object’s hash code allows algorithms and data structures to put objects into compartments, just like letter types in a printer’s type case. The printer puts all “A” types into the compartment for “A”, and he looks for an “A” only in this one compartment. This simple system lets him find types much faster than searching in an unsorted drawer. That’s also the idea of hash-based collections, such as HashMap and HashSet.
但我不明白。这里提到了什么想法? HashMap 或 HashSet 与哈希码有什么关系?
编辑:
以HashSet
为例。
假设它存储 7 个对象(让我们用字母表示它们),它们可以是从 A 到 E 的任何对象。假设它在第 0 个索引位置有 A,B 在第 1 个位置,在第二个位置,A 在第三个位置索引,然后在第四个索引处再次出现 A,然后在第五个索引处出现 D,在第六个索引处出现 E。等等。这是一种存储形式。
hashSet => [A, B, C, A, A, D, E]
然后还有另一种存储形式,其中所有三个 A 都放在一个隔间中,然后 B 在另一个隔间中,C 在另一个隔间中,D 和 E 在另外两个隔间中。
基于hashCode的分类=> [A, A, A], [B], [C], [D], [E]
现在如果我检查 hashSet.contains('A')
,它会直接查看包含 A
的隔间,这是第一个隔间,并为隔间的每个成员计算 A.equals(member-of-compartment)
?
我说得对吗?
HashMap 或 HashSet 就像带隔层的抽屉。这些数据结构使用 hashCode 将对象放在正确的隔间中。
一个非常简单的Strings hashCode(不是Java用的那个,而是现实生活中用的比较多的那个)就是String的第一个字母。这就是很多人用来把东西放在正确的隔间里的方法。
所以无论是HashMap还是HashSet,都是先根据hashCode查找合适的隔间来搜索对象。一旦他们找到了合适的隔间,他们就会从前到后查看以找到合适的物品(但理想情况下,每个隔间中只有很少的物品)
编辑:
您在编辑中使用 HashSet 是正确的。 (如果您将 hashCode 函数实现为始终 return 相同的值,比如零,那么它将像 "hashSet => [A, B, C, A, A, D, E]" 一样工作 - 它会将所有内容放入一个 bucket/compartment)
请注意,HashMap 和 HashSet 在实现方式上几乎没有区别。 HashSet 只是一个 HashMap,它只使用键并使用单个 pre-defined 值来指示键存在于映射中。
Hash-based collection 具有通常称为 桶 的内容。所有具有相同散列码的 object 都进入同一个桶。这与打印机的类型案例示例的想法相同。 hash-based collection 的桶就像打印机的类型盒隔层。
所有 "A" 都进入同一个隔间,就像所有具有相同哈希码的 object 进入同一个桶一样。
打印机根据它是哪个字母来决定哪个隔间,而不考虑类型。这里的"hash code"操作就是类型是哪个字母。
类似地,hash-based collections 需要找到 object 属于哪个桶。他们通过获取 object 的哈希码来做到这一点。
就像打印机只需要在 "A" 隔间中查找所需的特定 "A" 一样,hash-based collection 调用 hashCode()
方法来确定要查找哪个存储桶以查找 object.
打印机仍然需要目视检查隔间中的每个 object 是否有 he/she 需要的东西。同样,一个 hash-based collection 仍然需要找到正确的 object,即使多个 object 在同一个桶中。 hash-based collection 调用 equals
以查看 object 的键是否存在。