Java集合--tableSizeFor

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

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;
}

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

运行一个例子看看blog

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 输出16hash

输入18 输出32table

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

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

每一次右移以后与上一次的结果作按位或操做(只要有一个位是1,结果就是1),经过几回操做以后将本来二进制最高位为1的后面几位所有至1,最后再加1,获得一个2的指数幂。map

至于为何一开始要执行 n = c - 1; 这是为了防止 c 已是2的幂,若是 c 已是2的幂, 又没有执行这个减1操做,则执行完后面的几条无符号右移操做以后,返回的结果将是这个c的2倍。二进制

相关文章
相关标签/搜索