为什么HashSet的名字中有“Hash”?

时间:2010-11-03 01:48:13

标签: java hashmap hashset

为什么Hashset称为“哈希”集?

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

我假设它被称为HashSet,因为当我们添加()时,值被散列并存储以保持其唯一性。但为何过度杀伤?我们并不像在哈希表中那样关心数据的“平等分配”。

4 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:4)

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

答案 2 :(得分:2)

HashSet(与HashMap一样)使用哈希来实现O(1)摊销设置/测试/删除性能。(在这里有一些不正确的假设关于HashSet不使用散列的问题。)

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

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

请务必遵循Object wrt中的要求设置。 hashCodeequals或对象可能会丢失。尊重规则的糟糕散列函数仍然有效 - 尽管性能可能很差。 (可变对象在哈希ADT中使用尤其有问题,因为哈希码和/或相等可能并不总是稳定的。)

答案 3 :(得分:0)

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