一段神奇的算法

一段神奇的算法

閱讀hashmap源碼時(shí),看到了一段神奇的代碼,如下所示:

static final int tableSizeFor(int cap) {
    int n = cap - 1; // step 1
    n |= n >>> 1; // step 2
    n |= n >>> 2; // step 3
    n |= n >>> 4; // step 4
    n |= n >>> 8; // step 5
    n |= n >>> 16; // step 6
    return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; // step 7
}

這段代碼啥意思呢?這段代碼是初始化容量時(shí)會調(diào)用的,用于計(jì)算擴(kuò)容閾值。
這段代碼的目的是為了計(jì)算大于等于cap的最小2的冪,如cap=2,輸出2;cap=3,輸出4;cap=17,輸出32。

科普:

n >>> 1:是無符號右位移運(yùn)算,向右位移1位,左邊補(bǔ)0;
n |= n:位或運(yùn)算,0 | 0 = 0;0 | 1 = 1;1 | 1 = 1;1 | 0 = 1。即只要有1則為1。

以下以cap=121為例:
step 1:n = 120
step 2:
120的二進(jìn)制形式為:0111 1000
n >>> 1:0011 1100
n |= n:
0111 1000
0011 1100
——————————————————
0111 1100
輸出:n = 124
step 3:
124的二進(jìn)制形式為:0111 1100
n >>> 2:0001 1111
n |= n:
0111 1100
0001 1111
——————————————————
0111 1111
輸出:n = 127
step 4:
124的二進(jìn)制形式為:0111 1111
n >>> 4:0000 0111
n |= n:
0111 1111
0000 0111
——————————————————
0111 1111
輸出:n = 127
step 5:
124的二進(jìn)制形式為:0111 1111
n >>> 8:0000 0000
n |= n:
0111 1111
0000 0000
——————————————————
0111 1111
輸出:n = 127
step 6:
124的二進(jìn)制形式為:0111 1111
n >>> 16:0000 0000
n |= n:
0111 1111
0000 0000
——————————————————
0111 1111
輸出:n = 127
step 7:127 > && 127 < MAXIMUM_CAPACITY,輸出最終結(jié)果:128

此算法巧妙的地方在于,cap的最高位肯定是1,第一次向右位移1位后,再與原值進(jìn)行位或操作,結(jié)果是最高的兩位是1。接著向右位移2位再位或,得到最高的四位是1。同理,將得到一連串的1,即為結(jié)果。

至于step 1為何要先減去1,目的在于保證結(jié)果是大于等于cap的最小2的n次冪。如cap為8,預(yù)期的輸出也應(yīng)該為8。若不先減去1,則將輸出16,與預(yù)期不符。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容