HashMap中的tableSizeFor(int cap)算法----JDK1.8

  首先我们看下源码式怎么写的:

/**
 * 返回的是大于等于cap的最小的2的幂
 */
static final int tableSizeFor(int cap) {
    int n = cap - 1;// 防止传进来的就是2的次幂,导致返回的值必定是cap的2倍
    n |= n >>> 1;
    n |= n >>> 2;
    n |= n >>> 4;
    n |= n >>> 8;
    n |= n >>> 16;
    // 上面几步操作就是为了保证n算出来的是大于等于cap的最小的2的幂
    // 下面核心: n + 1
    return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;// 不能大于最大的值,返回值也不能小于0
}

  开始的时候很奇怪,为什么要这么做,然后查了很多资料,多少知道点了。但是还是不如自己动手来的快。下面来看下随便取几个数计算下最后的值是如何的:

cap = 16
n = 15:
0000 0000 0000 0000 0000 0000 0000 1111

n |= n >>> 1
n >>> 1:
0000 0000 0000 0000 0000 0000 0000 0111
n:
0000 0000 0000 0000 0000 0000 0000 1111

n |= n >>> 2:
n >>> 2:
0000 0000 0000 0000 0000 0000 0000 0011
n:
0000 0000 0000 0000 0000 0000 0000 1111

......

n:
0000 0000 0000 0000 0000 0000 0000 1111

n+1
0000 0000 0000 0000 0000 0000 0001 0000
16确实是 >= 16的最小2次幂
-----------------------------------------------------------------------
cap = 10
n = 9:
0000 0000 0000 0000 0000 0000 0000 1001

n |= n >>> 1
n >>> 1:
0000 0000 0000 0000 0000 0000 0000 0100
n:
0000 0000 0000 0000 0000 0000 0000 1101

n |= n >>> 2:
n >>> 2:
0000 0000 0000 0000 0000 0000 0000 0011
n:
0000 0000 0000 0000 0000 0000 0000 1111

......

n:
0000 0000 0000 0000 0000 0000 0000 1111

n+1
0000 0000 0000 0000 0000 0000 0001 0000
16确实是 >= 10的最小2次幂

  这样的好处就是:一定可以获取小于当前cap的最小二次幂的数。

posted @ 2019-10-26 16:30  小留情  阅读(90)  评论(0)    收藏  举报