作者:信雨2502873867 | 来源:互联网 | 2023-02-03 18:01
我正在检查它的实现,HashMap
并且在其中put
我看到在计算哈希之后,计算哈希的索引,就像这样int i = indexFor(hash, table.length);
,并且它被用作底层地图的索引.
/**
* Returns index for hash code h.
*/
static int indexFor(int h, int length) {
return h & (length-1);
}
我搜索没有找到任何解释我的问题,为什么再次计算哈希索引,用作底层数据结构的最终索引.与使用哈希作为索引相比,它有什么优势.
我知道它只是按位而已,但我想知道为什么会这样做.
1> dimo414..:
对象的哈希码可以是int
-2 ^ 31和2 ^ 31-1之间的任何值.哈希表使用的基础数组不会具有相同的范围(没有负数,对于一个,可能不是那么大),因此必须有一些操作将哈希代码从其原始范围转换为0和0之间的一个数组的长度.
因为HashMap
始终使用大小为2的幂(例如,16,32,64等)的数组使用&
是将哈希码映射到标记的有效方式,因为它简单地剥离其他位.如果其他散列表实现不将其数组大小限制为2的幂,则可以使用模数来实现类似的效果.
另见https://en.wikipedia.org/wiki/Hash_table#Collision_resolution
@pjj内部`hash()`方法用于完全不同的目的,即尝试最小化某些类型的哈希值的哈希冲突.为了您的问题,请忽略该电话.---对于你的问题,`hashCode()`可以返回整个`int`范围内的整数,但哈希表只有X桶.要将哈希代码"映射"到存储桶,您需要计算`hashCode()%X`以生成有效的存储桶编号(使用*unsigned*integer math).由于X始终是2的幂,因此慢速`%`模数运算符可以用更快的按位`&'运算符替换.