【问题标题】:Why does HashSet have "Hash" in its name?为什么HashSet的名字里有“Hash”?
【发布时间】:2010-11-03 01:48:13
【问题描述】:

为什么Hashset被称为“Hash”-set?

我知道我们称之为 hashtable 或 hashmap,因为它是一个键值存储,当我们 put() 时,键被散列并使用良好的散列函数均匀分布。

我假设它被称为 HashSet,因为当我们 add() 时,该值被散列并存储以保持其唯一性。但为什么要矫枉过正呢?我们并不真正关心数据的“平均分布”,就像我们在哈希表中所做的那样。

【问题讨论】:

  • 可能是因为它是一个由“HashMap”支持的Set,所以它在幕后具有那种性能。
  • “随机存储”是什么意思?您的哈希表理论似乎更需要完善。
  • 一个“好的”散列函数的责任是尽可能多地保持熵。这样散列的键就被平均分配了。
  • 均匀/均匀分布不是随机的。
  • 是的,明白了。问题更新了:)

标签: java hashmap hashset


【解决方案1】:

我们确实关心平均分配,因为我们希望基本Collection 操作的时间性能保持不变。为了尊重SET 的基本规则,没有两个对象是相等的,我们希望快速找到潜在相等的匹配。 HashSet 是一种相当不错的方法。与理论上的 ArraySet 相比,其中添加新元素是一种线性时间操作,用于迭代并检查每个现有条目是否相等。

【讨论】:

    【解决方案2】:

    HashSet 被称为HashSet,因为散列对其功能确实很重要。像contains(Object)(可以说是Set中最重要的方法)和remove(Object)这样的操作可以通过使用对象的哈希码(通过HashMap)在恒定时间内工作。

    【讨论】:

    • 好吧,无论如何,摊销恒定时间。
    【解决方案3】:

    HashSet(如 HashMap)使用哈希来实现 O(1)amortized 设置/测试/删除性能。(在关于 HashSet 不使用散列的问题。)

    现在,在 Java 中,所有对象都是“可散列的”——也就是说,它们有一个 hashCode() 函数(因为它们是 Object 的后代)。这个散列函数的质量将允许散列算法通过“通过桶[均匀地]传播对象”来达到上述预期的性能特征。 (hashCode/equals 的默认 Object 实现相当于 object-identity。通常这应该为任何子类更改。)

    但是,如果您的类实现 hashCode 很差(例如,所有值都返回 1),那么 HashSet/HashMap 的性能将因此受到很大影响(对于任何非平凡的 n)。重要的是要注意 hashCode 确定 bucketequals 确定可以使用的实际相等性即使哈希码是唯一的和/或者没有冲突(例如,为了确保测试/获取不会返回误报——可以想象它可以在非冲突集/插入上被消除)。

    只需确保遵循Object wrt 中的要求设置即可。 hashCodeequals 或对象可能丢失。遵守规则的不良散列函数仍然可以工作——尽管性能可能很差。 (可变对象在哈希 ADT 中使用尤其成问题,因为哈希码和/或相等性可能并不总是稳定的。)

    【讨论】:

      【解决方案4】:

      什么“矫枉过正”?任何 X 的 HashXXX 的想法是提供 O(1) 性能,这是通过散列实现的。如果您不想要 O(1) 性能,请不要使用它。以 TreeSet 为例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-06-28
        • 2016-03-26
        • 1970-01-01
        • 2018-02-18
        • 2020-08-04
        • 2015-09-25
        • 1970-01-01
        相关资源
        最近更新 更多