【HashMap擴容相關的蛛絲馬跡】位運算與取模的奇妙關係

給定一個數保證輸出一定是大於輸入值的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的冪那豈不是很浪費?這樣做難道僅僅因爲爲了優化一個取模運算?(引出平攤分析)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章