为什么在HashMap操作的复杂性中不考虑哈希函数的复杂性?

时间:2018-01-11 18:19:56

标签: java hashmap

对于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)?

3 个答案:

答案 0 :(得分:4)

当您根据N计算时间复杂度时,您必须首先确定N代表的内容。当我们讨论HashMap操作的复杂性时,N表示HashMap的大小(即HashMap中存储的键值对的数量)。

给定密钥的hashCode()的时间复杂度不依赖于HashMap中的条目数。因此,计算O(1)需要hashCode()时间(假设示例中String键的长度不是Map大小的函数 - 我们可以构造HashMap<String,String> iMap个字符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是字符串的长度。但是一旦你拥有它,无论你使用它多少次,你都可以拥有它。因此,它的成本被认为是不变的。