对于HashMap<String, String> map
,每次将键值对插入到地图中时,都会计算哈希值 -
java.lang.String#hashCode
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
由于它非常不言自明,put操作的复杂性基本上是哈希计算的复杂性。
那么为put / get操作定义hashmap最坏情况时间复杂度的适当方法应该是什么?
如果您从哈希冲突角度看问题相同,可以在这里找到答案: Is a Java hashmap really O(1)?
答案 0 :(得分:4)
当您根据N
计算时间复杂度时,您必须首先确定N
代表的内容。当我们讨论HashMap
操作的复杂性时,N
表示HashMap
的大小(即HashMap
中存储的键值对的数量)。
给定密钥的hashCode()
的时间复杂度不依赖于HashMap
中的条目数。因此,计算O(1)
需要hashCode()
时间(假设示例中String
键的长度不是Map
大小的函数 - 我们可以构造HashMap<String,String>
i
个Map
个字符i
中有hashCode()
字符的O(N)
奇怪HashMap
,在该边缘情况下,O(N)
计算需要O(1)
时间,因此,所有hashCode()
操作都需要O(1)
次,而不是Map
。)
计算HashMap
后,需要Future
时间来确定密钥是否已存在于CompletableFuture
中(因为CompletionStage
中每个存储桶的平均条目数{1}}由常量绑定。
答案 1 :(得分:4)
Big O表示法正在谈论操作的复杂性。当涉及更多元素时,大多数操作变得更复杂(即花费更多时间),并且符号描述了复杂性相对于元素数量的增长方式。
使用O(1),表示操作与所涉及的元素数量无关。由于它自己的原因,哈希操作可能很快或很慢,但无论你有一个1元素的HashMap还是它们的googolplex,速度都不会改变。
应该注意的是,O(1)是摊销平均值,不能保证。最坏的情况被认为是O(n),假设是每次都返回相同散列的散列函数,但是可以想象(如评论中的user889742所提出的)具有故意错误的散列码函数,其执行甚至比这一点。
答案 2 :(得分:2)
您必须知道(1)
的用途。它是数组中元素的数量。插入HashMap的成本不会根据地图中的元素数量而变化(假设您在结构的整个生命周期内分摊了插入成本。)
正确的是,计算String
的hashCode是O(n)
,其中n
是字符串的长度。但是一旦你拥有它,无论你使用它多少次,你都可以拥有它。因此,它的成本被认为是不变的。