源码:还不懂HashMap的tableSizeFor()方法原理?看这篇就够了。

还不懂HashMap的tableSizeFor()方法?看这篇就够了。

先上源码

 /**
 *这里要计算一个值,这个值要为2的n次方的值,要大于或等于cap(参数),并且最接近的。就比如30, 最接近的就是32.
 **/
 static final int tableSizeFor(int cap) {
        int n = cap - 1;//这一步在后面说明,为啥-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;
    }
	

算术符号说明:
1.n >>> 1(无符号右移): 二进制010,往右边移动一位变成001.【高位用0补充】
2. | (或): 1 | 0 为 1。

1.n |= n >>> x 说明

1.1算法推理说明

假如 n = 2^15+1 二进制为 0100000000000001, 那么计算tableSizeFor后的值为2^16 =1000000000000000 。(参数cap假设为2^15+2)

对比一下2^15+1 和 2^16 的二进制码

0100000000000001(2^15+1)
1000000000000000 (2^16)

对比说明:就是将2^15+1的最高位二进制位往左移一位, 后面的全部归零。

算法思路(重点): 将【2^15】0100000000000001 变成【0111111111111111】 ,然后再加1 就成了【2^16】1000000000000000。(这里是通过二进制的思维理解的)

1.2源码说明:
1. n |= n >>> 1 【分解为: n = n | (n>>>1)】 , n = 0100000000000001
0100000000000001( n )
0010000000000000(n>>>1 )
0110000000000000(n | (n>>>1) 最终结果)

简单的理解为:1 -> 变成了 11。其实就是将一个1 多复制了一个, 变成了 2个1

2. n |= n >>> 2
0110000000000000( n )
0001100000000000(n>>>2 )
0111100000000000(n | (n>>>2) 最终结果)

简单的理解为:11 -> 复制变成了 1111。

剩下怎么玩? 继续复制就完事了.

3. n |= n >>> 4
0111100000000000( n )
0000011110000000(n>>>4 : )
0111111110000000(最终结果)

简单的理解为:1111 -> 复制变成了 11111111。

4. n |= n >>> 8
0111111110000000( n )
0000000011111111(n>>>8 )
01111111111111111(最终结果)

最后变成了:0111111111111111。

5.还有最后一步 n |= n >>> 16;
0111111111111111 ( n )
00000000000000 (n>>>16 : 全是0,因为01111111111111111高位全是0, 太长了没写。)
01111111111111111(最终结果 )

最后将【2^15】0111111111111111 + 1 就会变成 1000000000000000【2^16】。

2.源码int n = cap - 1 说明

理解了上面的的思路的话,这一步就好理解了。
int n = cap - 1; //如果不这么做,按照上面的思路计算会导致得不到最接近的结果。
比如当cap = 32的时候,没有-1这个步骤,计算后的结果为64。

1.100000(32) 通过上面的步骤计算会变成 111111(63)
2.111111(63)+ 1 会变成100000 0( 64)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值