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; //这里调用了tableSizeFor方法,目的就是求不小于给定的初始容量的最小二次幂 //二次幂是HashMap 中的初始容量规定了必须是2的幂次 this.threshold = tableSizeFor(initialCapacity); }
然后再来看看tableSizeFor这个方法
static final int tableSizeFor(int cap) { //这里默认减一是为了防止给的初始容量为2的幂数,最后返回比它的二次幂数大一倍的数 //首先知道 >>>表示首先转成2进制数,然后无符号右移,高位取0 |= 表示进行 或 运算后再把运算结果赋值给 n 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; }
接下来就分析为什么要进行无符号右移的这一系列 *** 作,举个例子通过表格来看下吧
进行了这五次位或运算后发现了本质就是除了最高位,给低位全部赋值给1.
这样找比这个二机制数大一点的数目的就差一步了,
所以最后返回的就是+1,
就达到找到比这个数大或者等于的最小符合要求的二进制数作为容量.
至于减1也就能理解了,如果不减去1,这个数的最低位都是1,再加上1,肯定是原来的两倍了,这就不符合要求了.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)