給定一個數保證輸出一定是大於輸入值的2的最小冪
- HashMap的tableSizeFor實現了這個函數,下面是細節解析
static final int tableSizeFor(int cap) { //假設傳入3和4
//這裏-1是爲了防止cap已經是2的冪時得到cap*2的結果
int n = cap - 1; //3變2 4變3
//這裏2的二進制就是10 | 01 也就變成了二進制的11十進制是3
//同樣3的二進制是11 | 01 還是 11
n |= n >>> 1;
//這裏2的二進制就是10 | 01 也就變成了二進制的11十進制是3
//同樣3的二進制是11 | 01 還是 11
//此時傳入的2變成了3,4也變成了3
//後續操作是針對cap較大時的操作,可以省略掉
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就是2的冪*/;
}
應用場景
希望只有一個 i & n就可以實現模運算的場景
例如netty的EventLoop分配
例如HashMap的hash查找分配
更多
(1)思考一下如果我希望hashmap可以一邊被我遍歷還一邊擴容,我該怎麼去遞增table數組的索引?如果是縮容呢?
(2)HashMap每次擴容都是2的冪那豈不是很浪費?這樣做難道僅僅因爲爲了優化一個取模運算?(引出平攤分析)