Java中的<<=运算符是什么意思?

5
请您解释一下从HashMap构造函数的代码片段,特别是这行代码:capacity <<= 1:
这行代码实际上是将容量(capacity)的值左移一位。在Java中,左移运算符“<<”表示将一个数的二进制形式向左移动指定的位数,并在右侧插入零。例如,对于数字3(二进制为11),执行3 << 1后得到的结果是6(二进制为110)。
因此,在HashMap的构造函数中,该行代码实际上将初始容量乘以2。这是因为使用左移运算符比简单地乘以2更高效。
// Find a power of 2 >= initialCapacity
198         int capacity = 1;
199         while (capacity < initialCapacity)
200             capacity <<= 1;
4个回答

11

这与capacity = capacity << 1;相等。

该操作将容量的位左移一位,相当于乘以2。

你发布的具体代码是为了找到比initialCapacity大的最小2次幂。

因此,如果initialCapacity为27,则循环后capacity将为32(2^5)。


1
不过并非严格等同。可能会应用不同的优先级规则。 - Romain
1
@Geek 这个逻辑是通过重新散列和位掩码来实现比使用“%”并处理符号(涉及分支)更快的计算。 - Peter Lawrey
1
@Geek 我怀疑避免分支预测失误是主要的收益。 ;) - Peter Lawrey
@Geek,主要原因是与按位与相比,模运算的成本相当昂贵。 - bestsss
1
@Peter,使用模数运算在素数大小的表中是合理的,因为它可以减少碰撞。您所解释的位混淆可以提高碰撞的减少效果。在java.util.HashMap中,碰撞会导致缓存未命中,这种情况有点昂贵...开放地址表通常在pow2大小的表中更好,而且碰撞更便宜。总的来说,就像我多次声明的那样,java.util.HashMap很糟糕。 - bestsss
显示剩余10条评论

4
就像var += 1大约等于var = var + 1一样,这里看到的var <<= 1大约等于var = var << 1,它是"将var设置为经过var的一次1位二进制左移的结果"。
在这个非常特殊的情况下,实际上它是一个略微(运行时)更快的表示capacity *=2的方式(因为一个1位的按位左移相当于乘以2)。

3

这相当于

capacity = capacity << 1;

这个方法将capacity中的位向左移动一位(例如,00011011变为00110110)。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接