初探HashMap之構造方法

1.建立HashMap時傳入初始化容量和負載係數

initialCapacity(初始化容量):顧名思義,這個參數定義了這個HashMap的初始大小;小於零會拋出非法參數異常,大於MAXIMUM_CAPACITY(2的三十次方)則默認等於2的三十次方
loadFactor(負載因子):html

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);
}

threshold:當你的HashMap須要擴容時,擴容容量(添加方法put會用到此方法)java

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;
}

">>>":無符號右移(至關於加一)
"|="作或運算後把值存到左邊的變量("或運算":有1結果爲1,全爲0結果爲0)
爲何要對cap作減1操做?這是爲了防止cap已是2的冪.若是cap已是2的冪,又沒有執行這個減1操做,則執行完後面的幾條無符號右移操做以後,返回的capacity將是這個cap的2倍.最後+1,使之成爲2的冪
很是牛的一個算法,用於找到大於等於initialCapacity的最小的2的冪(不懂的http://www.th7.cn/Program/jav... 這裏不作贅述)算法

2.建立HashMap時只傳入初始化容量

public HashMap(int initialCapacity) {
    this(initialCapacity, DEFAULT_LOAD_FACTOR);
}

默認負載因子DEFAULT_LOAD_FACTOR = 0.75fthis

3.建立HashMap時不傳入任何參數

public HashMap() {
    this.loadFactor = DEFAULT_LOAD_FACTOR;
}

4.建立HashMap時傳入一個實現了Map接口的對象,此HashMap建立後會包括此Map的全部內容

public HashMap(Map<? extends K, ? extends V> m) {
    this.loadFactor = DEFAULT_LOAD_FACTOR;
    putMapEntries(m, false);
}
final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
    int s = m.size();
    if (s > 0) {
        if (table == null) {
            float ft = ((float)s / loadFactor) + 1.0F;
            int t = ((ft < (float)MAXIMUM_CAPACITY) ?
                     (int)ft : MAXIMUM_CAPACITY);
            if (t > threshold)
                threshold = tableSizeFor(t);
        }
        else if (s > threshold) // 傳入Map的size大於擴容容量,resize方法爲從新初始化一下容量
            resize();
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
            K key = e.getKey();
            V value = e.getValue();
            putVal(hash(key), key, value, false, evict);// 至關於put方法,請看下回分解
        }
    }
}

table:Node類型,作爲空判斷是否爲新建立.
ft:是否要擴容的操做(爲何+1我如今只有個模糊的感受,先留個坑)code

相關文章
相關標籤/搜索