为什么在HashMap中计算哈希码的索引

pjj*_*pjj 1 java hash hashmap

我正在检查它的实现,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);
}
Run Code Online (Sandbox Code Playgroud)

我搜索没有找到任何解释我的问题,为什么再次计算哈希索引,用作底层数据结构的最终索引.与使用哈希作为索引相比,它有什么优势.

我知道它只是按位而已,但我想知道为什么会这样做.

dim*_*414 5

对象的哈希码可以是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的幂,因此慢速`%`模数运算符可以用更快的按位`&'运算符替换. (3认同)