初始化ConcurrentHashMap时可以指定map大小,由于ConcurrentHashMap代码默认大小是2n,这里需要把用户填的大小转换成2n
备注:代码基于jdk 1.8.0_91
ConcurrentHashMap初始化代码
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);
这里重点看一下tablSizeFor()这个方法
/** * Returns a power of two size for the given target capacity. */ 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; }
这个方法主要作用是把用户输入的大小cap,转换成不小于cap的最小2 ^ n ,如cap = 9,返回16, cap = 5返回8
主要思路:如cap = 9,二进制 1001, 把后面3位全部变成1, 1111 + 1 = 10000 = 16.这里移位1, 2, 4, 8, 16主要是前面2, 4, 8, 16多个或运算的结果