Java8–HashMap之tableSizeFor
首先
基本类型:int 二进制位数:32
包装类:java.lang.Integer
最小值:Integer.MIN_VALUE= -2147483648 (-2的31次方)
最大值:Integer.MAX_VALUE= 2147483647 (2的31次方-1)
java 8HashMap 构造函数
java 8 中在创建hashMap的时候有个构造函数如下:
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);
}
其中initialCapacity是初始容量,这个容量经过tableSizeFor加工后就变为了大于输入参数且最近的2的整数次幂的数,当然如果输入参数大于230则会返回230,因为int最大是231-1不是2的倍数,最大的2的次方就是230。
tableSizeFor解析
java8源码如下:
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;
}
详解如下:
先来分析有关n位操作部分:先来假设n的二进制为01xxx…xxx。接着
对n右移1位:001xx…xxx,再位或:011xx…xxx
对n右移2为:00011…xxx,再位或:01111…xxx
此时前面已经有四个1了,再右移4位且位或可得8个1
同理,有8个1,右移8位肯定会让后八位也为1。
综上可得,该算法让最高位的1后面的位全变为1。
最后再让结果n+1,即得到了2的整数次幂的值了。
由于int是32位,所以>>>16便能满足。
备注
为什么最后写到n|n >>> 16?我们知道int范围在-231~231-1,因此对于int最大的2次幂数为2^30,这也就是MAXIMUM_CAPACITY的值。c超过这个值就会返回MAXIMUM_CAPACITY。
而这边代码中一共右移了1+2+4+8+16=31位,因此可以保证高位1以下的低位都会变成1.