有人可以向我解释静态HashMap#hash(int)方法吗?
产生均匀分布的哈希的背后的理由是什么?
/**
* Applies a supplemental hash function to a given hashCode, which
* defends against poor quality hash functions. This is critical
* because HashMap uses power-of-two length hash tables, that
* otherwise encounter collisions for hashCodes that do not differ
* in lower bits. Note: Null keys always map to hash 0, thus index 0.
*/
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);
}
一个例子将使它更容易消化。
澄清 我知道运算符,真值表和按位运算。我只是无法真正解码实现,也无法真正评论。甚至是背后的原因。
>>>
是逻辑右移(无符号扩展)(JLS 15.19 Shift
Operators
),并且^
是按位异或(JLS
15.22.1 Integer Bitwise
Operators
)。
关于这样做的原因,文档提供了一个提示:HashMap
使用2的幂的长度表,并通过掩盖掉哈希码的较高位并仅获取其较低位来哈希键。
// HashMap.java -- edited for conciseness
static int indexFor(int h, int length) {
return h & (length-1);
}
public V put(K key, V value) {
int hash = hash(key.hashCode());
int index = indexFor(hash, table.length);
// ...
}
因此,hash()
尝试使相关性与较高的位有关,否则将被屏蔽掉(indexFor
基本上丢弃的较高位,h
而仅在处使用较低的k
位length == (1 << k)
)。
将此与Hashtable
使用密钥的哈希码的方式(应该没有二乘幂长度表)进行对比。
// Hashtable.java -- edited for conciseness
public synchronized V get(Object key) {
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % table.length;
// ...
}
通过执行更昂贵的%
操作(而不是简单的位屏蔽),的性能对Hashtable
在较低位(尤其table.length
是素数)中分布较差的哈希码不太敏感。
问题内容: 谁能详细解释这种方法,谢谢。 问题答案: 设计通用哈希码的问题之一是,您将所有这些工作都放在了确保良好的位扩展上,然后有人来使用并以完全撤消的方式使用它。 让我们以一个带有X和Y(均为整数)的坐标类的经典示例为例。 这是一个经典的示例,因为人们会用它来证明这不是一个很好的哈希码,因为通常会有多个对象,其中(所有哈希都为0)或X和Y为Y和X的对象其他(将散列相同)和其他情况下,我们最终得
本文向大家介绍请你说一下解决hash冲突的方法?相关面试题,主要包含被问及请你说一下解决hash冲突的方法?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 当哈希表关键字集合很大时,关键字值不同的元素可能会映象到哈希表的同一地址上,这样的现象称为哈希冲突。目前常用的解决哈希冲突的方法如下: 开放定址法: 当发生地址冲突时,按照某种方法继续探测哈希表中的其他存储单元,直到找到空位置为止。 再
我试图用这个键得到一个值。我正在使用get()方法。我的密钥是由int和String组成的对象。所以我提出反对 我收到了空的。当我查看去bug模式或打印密钥集时,我收到类似的消息 虽然我的钥匙应该是 为什么键看起来像这样而不是以及如何使用键获取值? 我在键中覆盖了字符串methid。它看起来更好,但我仍然有空值,我相信有一些价值。
本文向大家介绍Java ArrayList add(int index, E element)和set(int index, E element)两个方法的说明,包括了Java ArrayList add(int index, E element)和set(int index, E element)两个方法的说明的使用技巧和注意事项,需要的朋友参考一下 一般使用List集合,估计都是使用这个Arr
本文向大家介绍js数组去重的hash方法,包括了js数组去重的hash方法的使用技巧和注意事项,需要的朋友参考一下 对于 JavaScript 数组去除重复项,现在有多种方法,其中一种是hash,如下: 但是该方法并不严谨,无法区分数字 1 和 字符串 '1' 修改一下,加上数据类型判断: 至少现在对5种原始数据类型的值可以准确去重了,对某些引用类型的值──数组,函数,也可以,但是对象类型──{"
本文向大家介绍Hash表处理冲突的方法相关面试题,主要包含被问及Hash表处理冲突的方法时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 开放定址法 为产生冲突的地址求得一个地址序列(),其中。其中m为表的长度,而增量有三种取值方法,线性探测再散列,平方探测再散列,随即探测再散列。 链地址法 将所有Hash地址相同的记录都链接在同一链表中 再Hash法 同时构造多个不同的Hash函数,当产生