HashMap--容量初始化中的位运算(|=,>>>)

解析Java中HashMap如何通过位运算高效调整其容量至2的幂,确保高性能存储与检索。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

阅读JDK中HashMap源码中的代码,HashMap初始化的时候,上来进行一通边界判断,然后接下来你会发现一段奇怪的代码:

/**
     * Returns a power of two size for the given target capacity.
     */
    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;
    }

这一通|= >>>是在玩游戏吗…
当然不是…
这是一堆位运算,不熟悉的同学赶紧去菜鸟教程Java版回炉一下,菜鸟传送门

| =	    按位或赋值操作符。	C | = 2等价于C = C | 2
>>> 	按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。	A>>>2得到15即0000 1111

那么这么做的目的是什么呢?
为了炫技啊(好吧,为了快…)
因为HashMap要求它的容量需要时2的整数次幂。上边这一通运算的目的就是为了获得你大于等于预期值,并且为2的整数次幂的容量。
还是回到上面的这一堆位运算,

输入:199
整数,二进制码
198,11000110
231,11100111
255,11111111
255,11111111
255,11111111
255,11111111
x is:256

输入:1999
整数,二进制码
1998,11111001110
2031,11111101111
2047,11111111111
2047,11111111111
2047,11111111111
2047,11111111111
x is:2048

看明白了吧,实际上这一串逻辑是通过位运算把我们预期的值从第一个不为0的位开始,把后面的所有位都设置成1。
也就是获得2n-1的效果。

至于为什么代码的第一行要cap-1,最后取值的时候要+1,是因为上边的位运算在处理2n的值时,会得出2n+1


输入:4
4,100
4,100
6,110
7,111
7,111
7,111
x is:8

还有个问题就是为啥那么好玩的位运算写到16位就不写了呢…
那是因为1+2+4+8+16=31位,已经达到了Int的边界了…
不熟悉的话继续传送门啊^_^ ,菜鸟传送门

int:

int 数据类型是32位、有符号的以二进制补码表示的整数;
最小值是 -2,147,483,648(-2^31);
最大值是 2,147,483,647(2^31 - 1);
一般地整型变量默认为 int 类型;
默认值是 0 ;
例子:int a = 100000, int b = -200000。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值