我目前正在研究Java中的哈希表,我对哈希表的操作及其性能速度有疑问。
我读到哈希表可以在常量时间内实现插入,查找和删除等操作, O (1)。我试图弄清楚是什么使得哈希表的操作非常量时间以及其中一些操作会是什么?
我认为像size()
这样的操作会处于线性时间,因为速度取决于哈希表的大小,但我不确定。
对此的任何想法都将非常感激!
答案 0 :(得分:7)
在一个天真的实现中,计算大小将是线性的,是的。但是在变量中缓存大小是一个简单的优化,并且值得额外的几个字节以及在添加和删除元素时必须更新该变量的次要性能损失。
请记住,插入 O (1)摊销。它并不总是一个恒定的时间操作。如果哈希表过度增长,则插入将导致其大小调整, O ( n )操作。幸运的是,这些调整大小很少,其成本可以在其他 O ( n )插入中平均,平均只添加一个常数因子。
此外,插入,查找和删除平均都是 O (1),但它们可以是 O ( n )in最坏的情况。使用病态错误的哈希函数,它们的性能将严重降低。在最坏的情况下,所有元素都将添加到哈希表中的一个桶中,从而有效地将哈希表转换为链表。
实际上,in Java 8 they added an optimization to HashMap
。如果存储桶足够大且密钥为Comparable
,则它将使用二叉树而不是链接列表,从而将 O (n)的最坏情况性能改善为 O (log n )。