看了Java7的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);
}
在最后一行,HashMap的最大极限容量不再是java6的循环
tableSizeFor函数源码
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;
}
这里简单的5个>>>操作和 |= 操作变算出了大于
initialCapacity且小于2的N次方
第一次
n |= n >>> 1;
n最左边为“1”的bit位和后边一位(如果存在的话)都为“1”例如0000 11** **** ****
第二次
<pre name="code" class="html">n |= n >>> 2;
现在的n最左边为“1”的bit位和后边4位(如果存在的话)都为“1”例如 <span style="font-family: Arial, Helvetica, sans-serif;">0000 1111 **** ****</span>
类推
最后再+1便完成了是初始化大小为2的N次方
</pre><pre name="code" class="html">注意初始化时没有用到loadFactor。
此时HashMap还是个半成品,因为没用初始化table。
当第一次put时才真正初始化完成,初始化会检查table是否为null,第一次肯定成立,所以会调用resize()函数,如下
<pre name="code" class="html">if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
在resize()中会执行如下语句
<pre name="code" class="html"><pre name="code" class="html"> if (newThr == 0) {
float ft = (float)newCap * loadFactor;
newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
(int)ft : Integer.MAX_VALUE);
}
threshold = newThr;
@SuppressWarnings({"rawtypes","unchecked"})
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
table = newTab;
这里便用到了loadFactor初始化了 newThr,newThr即新的 threshold,同时初始化了table
</pre><pre name="code" class="html">菜鸟,初次写,请多指教。贵在天天总结,谢谢。