Java 为什么HashSet有;“散列”;以它的名义?

Java 为什么HashSet有;“散列”;以它的名义?,java,hashmap,hashset,Java,Hashmap,Hashset,为什么Hashset被称为“Hash”-set 我知道我们调用hashtable或hashmap,因为它是一个键值存储,当我们put()时,使用一个好的hash函数对键进行散列并均匀分布 我假设它被称为HashSet,因为当我们添加()时,该值被散列并存储以保持其唯一性。但为什么会有过度杀伤力呢?我们并不像在哈希表中那样真正关心数据的“均匀分布”。我们关心的是均匀分布,因为我们希望在基本的集合操作中保持恒定的时间性能。为了遵守集合的基本规则,没有两个对象是相等的,我们希望快速找到可能相等的匹配H

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

我知道我们调用hashtable或hashmap,因为它是一个键值存储,当我们put()时,使用一个好的hash函数对键进行散列并均匀分布


我假设它被称为HashSet,因为当我们添加()时,该值被散列并存储以保持其唯一性。但为什么会有过度杀伤力呢?我们并不像在哈希表中那样真正关心数据的“均匀分布”。

我们关心的是均匀分布,因为我们希望在基本的
集合
操作中保持恒定的时间性能。为了遵守
集合
的基本规则,没有两个对象是相等的,我们希望快速找到可能相等的匹配
HashSet
是一种相当好的方法。与理论上的
ArraySet
相比,添加新元素是一个线性时间操作,用于迭代和检查每个现有条目的相等性。

HashSet
称为
HashSet
,因为hashing对其功能确实很重要。像
包含(对象)
(可以说是
集合
中最重要的方法)和
删除(对象)
这样的操作可以通过使用对象的哈希代码(通过
哈希映射
)在固定时间内工作。

什么是“过度杀戮”?对于任何X,HashXXX的思想是提供O(1)性能,这是通过哈希实现的。如果您不想要O(1)性能,请不要使用它。例如,使用树集。

HashSet(像HashMap一样)使用散列来实现O(1)摊销集/测试/删除性能。(关于HashSet不使用散列的问题中有一些不正确的假设。)

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

但是,如果您的类实现
hashCode
很差(例如,所有值返回1),那么HashSet/HashMap的性能将因此受到很大影响(对于任何非平凡的n)。重要的是要注意,
hashCode
确定bucket,但
equals
确定实际的相等性,即使hash代码是唯一的和/或没有冲突,也可以使用该相等性(例如,为了确保test/get不会返回假阳性,可以在非冲突集/插入上消除它)


只需确保遵循wrt中的要求设置。
hashCode
equals
或对象可能会丢失。遵守规则的糟糕的哈希函数仍然有效——尽管性能可能很差。(在散列ADT中使用可变对象尤其有问题,因为散列代码和/或相等可能并不总是稳定的。)

可能是因为它是一个由“HashMap”支持的集合,所以它在幕后具有这种性能。“随机存储”是什么意思?看起来你的哈希表理论需要改进。好的哈希函数的责任是尽可能多地保持熵。这样哈希键就可以被平均分割。均匀/均匀分布不是随机的。是的,明白你的意思了。问题更新:)好吧,不管怎样,摊销常数时间。