Java集合--tableSizeFor

在看 HashMap 源码的时候有这么一段代码

private static final int MAXIMUM_CAPACITY = 1 << 30;

private static final int tableSizeFor(int c) {
    int n = c - 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;
}

第一眼看上去完全看不懂,这几个右移按位或是什么意思

运行一个例子看看

private static final int MAXIMUM_CAPACITY = 1 << 30;

private static int tableSizeFor(int c) {
    int n = c - 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;
}

public static void main(String[] args) {
    System.out.println(tableSizeFor(6));
    System.out.println(tableSizeFor(7));
    System.out.println(tableSizeFor(10));
    System.out.println(tableSizeFor(15));
    System.out.println(tableSizeFor(18));
}

// 输出
8
8
16
16
32

输入6,7 都是输出8

输入10, 15 输出16

输入18 输出32

输出的都是2的指数幂,其实这个方法是用于找到大于等于输入参数的的最小的2的指数幂。为什么需要这样的方法,因为hashmap的容量大小都是2的指数幂。

以输入22为例子, n = c - 1, n 为 21

每一次右移之后与上一次的结果做按位或操作(只要有一个位是1,结果就是1),通过几次操作之后将原本二进制最高位为1的后面几位全部至1,最后再加1,得到一个2的指数幂。

至于为什么一开始要执行 n = c - 1; 这是为了防止 c 已经是2的幂,如果 c 已经是2的幂, 又没有执行这个减1操作,则执行完后面的几条无符号右移操作之后,返回的结果将是这个c的2倍。

 

 

转载于:https://my.oschina.net/u/232911/blog/2872356

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值