Why does HashMap.put both compare hashes and test equality?(为什么 HashMap.put 既比较哈希值又测试相等性?)
问题描述
我分析Java中的HashMap
源代码,得到一个关于put
方法的问题.
I analyse the HashMap
source code in Java and get a question about the put
method.
下面是JDK1.6中的put
方法:
Below is the put
method in JDK1.6:
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 && ((k = e.key) == key || key.equals(k))) 感到困惑
为什么会这样?
因为在Java超类Object
中,有一个contract of hashCode
and equals
:
Because in Java super class Object
, there is a contract of hashCode
and equals
:
如果两个对象根据equals(Object)方法相等,那么对两个对象中的每一个调用hashCode方法必须产生相同的整数结果.
If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
所以 key.equals(k)
意味着 key.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);
}
因此 key.hashCode() == k.hashCode()
意味着 e.hash == hash
.
那么为什么不是if ((k = e.key) == key || key.equals(k))这样的条件
?
推荐答案
这只是一个优化:比较两个整数比调用 equals()
更快.
It's just an optimization: comparing two integers is faster than calling equals()
.
如果两个hashcode不同,那么根据equals
和hashCode
的约定,map知道现有的key不等于给定的key,并且可以更快地进入下一个.
If the two hashcodes differ, then, based on the contract of equals
and hashCode
, the map knows that the existing key isn't equal to the given key, and can go faster to the next one.
这篇关于为什么 HashMap.put 既比较哈希值又测试相等性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么 HashMap.put 既比较哈希值又测试相等性?
基础教程推荐
- “未找到匹配项"使用 matcher 的 group 方法时 2022-01-01
- 设置 bean 时出现 Nullpointerexception 2022-01-01
- 无法使用修饰符“public final"访问 java.util.Ha 2022-01-01
- 减少 JVM 暂停时间 >1 秒使用 UseConcMarkSweepGC 2022-01-01
- Java Keytool 导入证书后出错,"keytool error: java.io.FileNotFoundException &拒绝访问" 2022-01-01
- 在 Libgdx 中处理屏幕的正确方法 2022-01-01
- 降序排序:Java Map 2022-01-01
- FirebaseListAdapter 不推送聊天应用程序的单个项目 - Firebase-Ui 3.1 2022-01-01
- 如何使用 Java 创建 X509 证书? 2022-01-01
- Java:带有char数组的println给出乱码 2022-01-01