美文网首页
HashMap如何计算Entry在桶中的下标?

HashMap如何计算Entry在桶中的下标?

作者: 汪和呆喵 | 来源:发表于2018-12-10 09:51 被阅读0次

我们知道HashMap内部包含了一个 Entry 类型的数组 table。

transient Entry[] table;

Entry 存储着键值对。它包含了四个字段,从 next 字段我们可以看出 Entry 是一个链表。即数组中的每个位置被当成一个桶(bucket),一个桶存放一个链表。HashMap 使用拉链法来解决冲突,同一个链表中存放哈希值相同的 Entry。

那么是如何计算Entry在桶中的位置的呢?

HashMap中的代码如下:

int hash = hash(key);
int i = indexFor(hash, table.length);

1 计算 hash 值

final int hash(Object k) {
    int h = hashSeed;
    if (0 != h && k instanceof String) {
        return sun.misc.Hashing.stringHash32((String) k);
    }

    h ^= k.hashCode();

    // 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);
}
public final int hashCode() {
    return Objects.hashCode(key) ^ Objects.hashCode(value);
}

2 取模

static int indexFor(int h, int length) {
    return h & (length-1);
}

这个位运算等同于:hash % length

是不是乍一看看不懂呢? 来解释一下:

令 x = 1<<4,即 x 为 2 的 4 次方,它具有以下性质:

x : 00010000
x-1 : 00001111
令一个数 y 与 x-1 做与运算,可以去除 y 位级表示的第 4 位以上数:

y : 10110010
x-1 : 00001111
y&(x-1) : 00000010
这个性质使 y & (x - 1)和 y 对 x 取模效果是一样的:

y : 10110010
x : 00010000
y%x : 00000010

我们知道,位运算的代价比求模运算小的多,因此在进行这种计算时用位运算的话能带来更高的性能。

总结:HashMap确定桶下标的最后一步是将 key 的 hash 值对桶个数取模:hash%capacity。
如果能保证 capacity 为 2 的 n 次方,那么就可以将这个操作转换为位运算。
在平时的开发中我们也可以利用这个特性,对一些算法运算的效率进行优化。

相关文章

  • HashMap如何计算Entry在桶中的下标?

    我们知道HashMap内部包含了一个 Entry 类型的数组 table。 transient Entry[] t...

  • HashMap的初始长度为什么是16

    当put方法调用,将entry放入数组的时候,需要计算entry的索引index。在hashmap中,index的...

  • Jdk7中java hashmap的特点

    架构简介Jdk7中的hashmap是基于数组和链表,具体就是table[]和Entry,很多人把Entry翻译成桶...

  • hashMap中的位运算

    HashMap中的位运算 1. 下标的计算 举例 扩容的计算。resize() = (oldCap & e.has...

  • HashMap

    HashMap集合中每个键值对也叫Entry,这些Entry分散的存储在一个数组中,这个数组是HashMap的主干...

  • Java - HashMap扩容为什么选用2倍

    做除余的时候2的倍数可以直接使用&进行快速计算 hashmap桶的下标,就是根据hashcode值取余来获取到具体...

  • HashMap源码解析

    java.util.HashMap 本质是一个Entry[]数组(哈希桶数组),用Key的哈希值对桶数组size取...

  • HashMap源码

    java.util.HashMap 本质是一个Entry[]数组(哈希桶数组),用Key的哈希值对桶数组size取...

  • HashMap下标计算详解

    HashMap 计算方法为:(n - 1) & hash 具体见putVal解读:由于n-1高位全部为0 因此(n...

  • Java基础

    Hashmap的原理,增删的情况后端数据结构如何位移 在JDK1.6,JDK1.7中,HashMap采用位桶+链表...

网友评论

      本文标题:HashMap如何计算Entry在桶中的下标?

      本文链接:https://www.haomeiwen.com/subject/dbzlhqtx.html