Mun*_*uno 7 java hashmap hashcode
根据这篇博客文章,HashMap 在已经检索到的哈希码上重新调用它自己的hashCode()(被调用的hash())实现.
如果key不为null,那么它将调用key对象的hashfunction,参见上面方法中的第4行,即key.hashCode(),所以在key.hashCode()返回hashValue之后,第4行看起来像
int hash = hash(hashValue)
现在,它将返回的hashValue应用到自己的散列函数中.
我们可能想知道为什么我们使用hash(hashValue)再次计算hashvalue.答案是,它防御质量差的哈希>函数.
HashMap能否准确地重新分配哈希码?HashMap可以存储对象,但是它无权访问将hashCode分配给其对象的逻辑.例如,hash()无法集成以下hashCode()实现背后的逻辑:
public class Employee {
protected long employeeId;
protected String firstName;
protected String lastName;
public int hashCode(){
return (int) employeeId;
}
}
Run Code Online (Sandbox Code Playgroud)
And*_*eas 14
所述hash()导出从实际的散列码的"改进的"哈希码,因此相等的输入将总是输出等于(来自jdk1.8.0_51):
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
Run Code Online (Sandbox Code Playgroud)
至于为什么哈希码需要改进,请阅读方法的javadoc:
计算key.hashCode()并将散列(XOR)更高的散列位降低.因为该表使用2次幂掩蔽,所以仅在当前掩码之上的位中变化的散列组将始终发生冲突.(在已知的例子中是一组Float键,在小表中保存连续的整数.)因此我们应用一个向下传播高位比特影响的变换.速度,效用和比特扩展质量之间存在权衡.因为许多常见的哈希集合已经合理分布(因此不会受益于传播),并且因为我们使用树来处理容器中的大量冲突,所以我们只是以最便宜的方式对一些移位的位进行异或,以减少系统损失,以及由于表格边界而包含最高位的影响,否则这些位将永远不会用于索引计算.
| 归档时间: |
|
| 查看次数: |
1091 次 |
| 最近记录: |