HashMap 的 tableSizeFor方法 JDK1.8版本源码解析

HashMap 的 tableSizeFor方法 JDK1.8版本源码解析,第1张

HashMap 的 tableSizeFor方法 JDK1.8版本源码解析
public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0) {
            throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity);
        }
        if (initialCapacity > MAXIMUM_CAPACITY) {
            initialCapacity = MAXIMUM_CAPACITY;
        }
        if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
            throw new IllegalArgumentException("Illegal load factor: " + loadFactor);
        }
        this.loadFactor = loadFactor;
        //这里调用了tableSizeFor方法,目的就是求不小于给定的初始容量的最小二次幂
        //二次幂是HashMap 中的初始容量规定了必须是2的幂次
        this.threshold = tableSizeFor(initialCapacity);
    }

然后再来看看tableSizeFor这个方法

    static final int tableSizeFor(int cap) {
    //这里默认减一是为了防止给的初始容量为2的幂数,最后返回比它的二次幂数大一倍的数
    //首先知道 >>>表示首先转成2进制数,然后无符号右移,高位取0
    |=  表示进行 或 运算后再把运算结果赋值给 n
       int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
 return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}

接下来就分析为什么要进行无符号右移的这一系列 *** 作,举个例子通过表格来看下吧

右移位数初始值右移值或运算后10000001x xxxxxxxx xxxxxxxx xxxxxxxx00000001 xxxxxxxx xxxxxxxx xxxxxxxx00000011 xxxxxxxx xxxxxxxx xxxxxxxx200000011 xxxxxxxx xxxxxxxx xxxxxxxx00000000 11xxxxxx xxxxxxxx xxxxxxxx00000011 11xxxxxx xxxxxxxx xxxxxxxx400000011 11xxxxxx xxxxxxxx xxxxxxxx00000000 001111xx xxxxxxxx xxxxxxxx00000011 111111xx xxxxxxxx xxxxxxxx800000011 111111xx xxxxxxxx xxxxxxxx00000000 00000011 111111xx xxxxxxxx00000011 11111111 111111xx xxxxxxxx1600000011 11111111 111111xx xxxxxxxx00000000 00000000 00000011 1111111100000011 11111111 11111111 11111111

进行了这五次位或运算后发现了本质就是除了最高位,给低位全部赋值给1.
这样找比这个二机制数大一点的数目的就差一步了,
所以最后返回的就是+1,
就达到找到比这个数大或者等于的最小符合要求的二进制数作为容量.

至于减1也就能理解了,如果不减去1,这个数的最低位都是1,再加上1,肯定是原来的两倍了,这就不符合要求了.

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5683207.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存