当前位置: 首页 > 知识库问答 >
问题:

为什么HashMap.put比较哈希和测试相等性?

贺彬
2023-03-14

我分析了Java中的HashMap源代码,并得到一个关于put方法的问题。

下面是JDK1.6中的put方法:

public V put(K key, V value) {
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key.hashCode());
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

我对if(e.hash==hash)的感到困惑

为什么情况是这样?

因为在Java超类对象中,有一个hashCode等于的契约:

如果根据equals(Object)方法两个对象相等,那么对两个对象中的每一个调用hashCode方法必须产生相同的整数结果。

因此,键。等于(k)表示键。hashCode()==k.hashCode()

hash()如下所示:

 static int hash(int h) {
    // This function ensures that hashCodes that differ only by
    // constant multiples at each bit position have a bounded
    // number of collisions (approximately 8 at default load factor).
    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);
}

因此,键。hashCode()==k.hashCode()意味着e.hash==hash

那么为什么条件不是if((k=e.key)==key | | key。等于(k))


共有3个答案

公良运锋
2023-03-14

“hash”变量的值可以与键hashcode不同。”hash变量是调用hash(key.hashCode())方法的结果。因此,需要比较散列值和键的相等性。

牟飞沉
2023-03-14

它只是尽可能避免方法调用:如果哈希(不是hashCode(),它是映射自己的哈希)不同于条目的哈希,它知道它根本不需要调用equals。只是优化了一点。

贝嘉泽
2023-03-14

这只是一种优化:比较两个整数比调用equals()要快。

如果两个hashCode不同,那么基于equalshashCode的约定,映射知道现有密钥不等于给定密钥,可以更快地转到下一个密钥。

 类似资料:
  • 我使用mitsuhiko的pbkdf2实现进行密码哈希: 此函数返回二进制摘要,然后将其编码在bas64中并保存到数据库中。此外,当用户登录时,Base64字符串被设置为cookie。 此函数用于密码哈希比较: 我想知道在安全性方面,二进制哈希和Base64字符串的比较是否有任何不同?例如,当用户登录时,我会计算提交密码的二进制摘要,从数据库中解码Base64字符串,然后比较两个二进制哈希,但是如

  • 我正在尝试使用Sinatra和BCrypt实现一种看似非常简单的身份验证方法,但显然我遗漏了一些东西... 用户会预先分配一个临时密码,该密码以明文形式存储在DB中。 我根据临时口令进行身份验证,然后创建salt和password_hash,并将它们作为字符串写入db(本例中为mongo)。 为了进行身份验证,我从db和用户口令中获取salt进行比较。 bcrypt::Engine.hash_se

  • 问题内容: 如果我想找出两个键中是否没有一个键与另一个键不同,并且该键的值彼此匹配,如何最好地比较两个键。 将A与B进行比较时,由于B和D键的不同,它应该会失败。 如何最好地比较未排序的哈希图? 问题答案: 做一个支票上两者秒。 注意: 如果您包含键,那没有问题,但是如果您的Map包含类型键,则需要确保您的类实现了。

  • 有人能告诉我如何从WooCommerce网络钩子中重新创建哈希以与请求中的“X-WC-Webhook-Signature”标头哈希进行比较吗? 留档指定哈希是从“有效负载”生成的,但我无法生成相同的哈希。 我的API是。NET Core 3.1 我尝试的第一件事: 第二个:

  • 问题内容: 我必须对指纹文件进行匹配才能匹配双峰。在2013年,对Java有何建议?我是否还应该比较文件大小,或者这是不必要的检查? 误报的可能性应该非常接近0 编辑:很多答案,谢谢。如今备份软件的标准是什么?SHA-256?更高?我猜md5不合适吗? 问题答案: 如果假阳性的概率必须 为零 ,而不是“比闪电击中的概率低”,则完全不能使用哈希算法;您必须逐字节比较文件。 值得一提的是,如果您可以使

  • JavaScript 有两种方式判断两个值是否相等。 等于操作符 等于操作符由两个等号组成:== JavaScript 是弱类型语言,这就意味着,等于操作符会为了比较两个值而进行强制类型转换。 "" == "0" // false 0 == "" // true 0 == "0"