【问题标题】:Algorithm used for bucket lookup for hashcodes [duplicate]用于哈希码的桶查找的算法[重复]
【发布时间】:2015-04-27 02:24:33
【问题描述】:

在大多数情况下,HashSet 的查找复杂度 O(1)。我知道这是因为对象保存在与对象的哈希码相对应的存储桶中。

当查找完成时,它直接进入桶并找到(如果同一个桶中存在许多对象,则使用equals)元素。

我一直想知道,它是如何直接进入所需的存储桶的?哪种算法用于桶查找?这不会增加总查找时间吗?

【问题讨论】:

  • 这个词是“算法”。它来自一个专有名称。缩写是不允许的,确实没有意义。
  • 下次会注意的:)
  • 基本上,bucket[o.hashCode() % buckets.length].
  • 它基本上是从数组中访问索引 i 。所以没有查找时间来达到索引 i。 i 由 hashcode%array.length 计算得出;并且哈希码是从 has 函数计算出来的。虽然它需要一些恒定的时间,并且 O(1) 表示它不依赖于元素的大小。
  • 每个答案都提供了更多见解!我不能全部接受:(

标签: java algorithm hashcode


【解决方案1】:

我一直在想,它是怎么直接进入到需要的bucket的呢?

哈希码是treated,用作数组的索引。

索引由hash & (array.length - 1) 确定,因为Java HashMap 的内部数组的长度始终是2 的幂。(这是hash % array.length 的更便宜的计算。)

每个“桶”实际上是一个链表(现在可能是一棵树),其中包含冲突哈希的条目被分组。如果有冲突,则在桶中进行线性搜索。

这不会增加总查找时间吗?

它会产生一些从内存中加载的成本。

【讨论】:

【解决方案2】:

通常,算法很简单

hash = hashFunction(key)
index = hash % arraySize

有关详细信息,请参阅哈希表上的 the wikipedia article

【讨论】:

    【解决方案3】:

    从内存中:HashSet实际上是由一个HashMap支持的,基本的查找过程是:

    • 获取密钥
    • 散列 (hashcode())
    • hashcode % 桶数
    • 转到该存储桶并计算 equals()

    对于一个集合,只有唯一的元素。我建议阅读 HashSet 的源代码,它应该能够回答您的问题。

    http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/HashMap.java#HashMap.containsKey%28java.lang.Object%29

    另请注意,Java 8 代码已更新,此说明涵盖了 Java 8 之前的代码库。我没有详细检查 Java 8 的实现,只是发现它是不同的。

    【讨论】:

    • 在一个集合中每个桶只能有一个元素是不正确的。如果您有冲突(具有相同哈希的两个不同元素),它们最终会在同一个存储桶中。在您链接的源代码中,您甚至可以看到每个存储桶都有一个 Entry 元素的链接列表。
    • 你说得对,我的意思是集合中只有唯一的键,没有重复。更新。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-19
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 2011-10-10
    • 1970-01-01
    相关资源
    最近更新 更多