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

本文深入解析HashMap的构造过程,特别是容量初始化和负载因子的设置。通过tableSizeFor方法,了解到如何确保容量为2的幂次,以优化哈希表性能。通过对位运算的分析,揭示了找到大于等于初始容量的最小二次幂的策略,确保HashMap的高效运行。
摘要由CSDN通过智能技术生成
/**
* 构造一个空的具有指定的初始容量和负载因子的 HashMap
*  initialCapacity  初始容量
*  loadFactor		负载因子
*  threshold 		下一个调整大小的值(容量*加载因子)
*/
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这个方法

/**
* 返回大于等于initialCapacity的最小的二次幂数值
*/
    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 xxxxxxxx
200000011 xxxxxxxx xxxxxxxx xxxxxxxx00000000 11xxxxxx xxxxxxxx xxxxxxxx00000011 11xxxxxx xxxxxxxx xxxxxxxx
400000011 11xxxxxx xxxxxxxx xxxxxxxx00000000 001111xx xxxxxxxx xxxxxxxx00000011 111111xx xxxxxxxx xxxxxxxx
800000011 111111xx xxxxxxxx xxxxxxxx00000000 00000011 111111xx xxxxxxxx00000011 11111111 111111xx xxxxxxxx
1600000011 11111111 111111xx xxxxxxxx00000000 00000000 00000011 1111111100000011 11111111 11111111 11111111

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值