Java8--HashMap之tableSizeFor

首先

基本類型:int 二進制位數:32
包裝類:java.lang.Integer
最小值:Integer.MIN_VALUE= -2147483648 (-2的31次方)
最大值:Integer.MAX_VALUE= 2147483647 (2的31次方-1)java

java 8HashMap 構造函數

java 8 中在建立hashMap的時候有個構造函數以下:git

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的次方就是230github

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便能知足。

WX20191119-153843@2x.png
而關於爲啥要int n = cap - 1;
用代碼解釋吧:
WX20191119-154531@2x.png
輸入以下:this

16
8

若是不減去1獲得的結果爲16顯然不對,輸入8的時候不小於輸入結果的最小2的次方應該是8。那麼這裏減一的意義就是避免這種狀況。spa

參考文章:
Java8—HashMap之tableSizeFor()
推薦一個寫的不錯的介紹hashmap的文章:
Java HashMap工做原理及實現code

相關文章
相關標籤/搜索