hashmap 源码-tableSizeFor方法

无参数构造器的初始容量和负载因子为16,0.75.

其他传入指定容量的构造器会根据传入的构造器设置容量为2^n 》=(容量),n取最小值。

static final int tableSizeFor(int cap) {
        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;
}

这个方法的作用是取到最小》=cap的2^n值

cap一定大于0,那么只要把最高位到末尾位全部变成1,然后加上1,就可以得到我们需要的值。

比如5,0000 0101 (1)-----》 0000 0111 (2)------> 0000 1000

        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;

这块代码,就是负责把最高位到末尾位全部变成1

先来一个简单的例子。根据公式 a|=b ----> a = a | b

比如:a = 2 | (2>>>1)
在这里插入图片描述

所以要从1开始,依次以2的倍数递增。1+2+4+8+16=31,可以把任意的int型变量,取到最小的那个2^n值,为了防止int溢出,jdk做了如下处理

static final int MAXIMUM_CAPACITY = 1 << 30; 2^30
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);

MAXIMUM_CAPACITY 这个值设计的很巧妙,恰好和tableSizeFor中的算法相辅,使得int不会溢出。因为int位数有32位,减去一位符号位,还有31位,方法的参数大于MAXIMUM_CAPACITY的值的都会被替换成MAXIMUM_CAPACITY,移位之后的阈值不会超过31位的范围。

static final int tableSizeFor(int cap) {
        int n = cap - 1; 
}

减一原因:

防止cap本身就是2^n,从而导致分配了多一倍的空间。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值