hashmap中的一些小點(個人總結)

  • capacity <<= 1:
            int i  = 1;

          //類似于 i++就是 i = i+1;的這結構
          //i = i<<1  i等于i乘以2的1次方
          //i <<= 1;
          //i = i<<2  i等于i乘以2的2次方,>>就是相除了
          i <<= 2;
          System.out.println("結果是:" + i);
  • java中有三種移位運算符:

// <<:左移運算符,num << 1,相當于num乘以2
// >>:右移運算符,num >> 1,相當于num除以2
// >>>:無符號右移,忽略符號位,空位都以0補齊
無符號右移的規則只記住一點:忽略了符號位擴展,0補最高位 無符號右移運算符>>> 只是對32位和64位的值有意義

            //保證hashCode 不同的算法
            //int 是4位byte的 4*8=32bit ,注意-->12+20=32
           //h>>>20是無符號右移運算,就是將int類型的h的二進制數字位往右移動,左邊移出來的空位補上0。
           //即為h = h ^ ((h >>> 20) ^ (h >>> 12));按位異或運算,僅當兩個對應的二進制位不相同時,結果為1;否則結果為0。
          static int hash(int h) {
             h ^= (h >>> 20) ^ (h >>> 12);
             return h ^ (h >>> 7) ^ (h >>> 4);
         }
  • 什么是哈希沖突:
  • 哈希計算就是努力的把比較大的數據存放到相對較小的空間中。最常見的哈希算法是取模法。
  • 取模法:數組的長度是5。這時有一個數據是6。那么如何把這個6存放到長度只有5的數組中呢。按照取模法,計算6%5,結果是1,那么就把6放到數組下標是1的位置。那么,7就應該放到2這個位置。到此位置,沖突還沒有出現。這時,有個數據是11,按照取模法,11%5=1,也等于1。那么原來數組下標是1的地方已經有數了,是6。這時又計算出1這個位置,那么數組1這個位置,就必須儲存兩個數了。這時,就叫哈希沖突。沖突之后就要按照順序來存放了。
  • 如果數據的分布比較廣泛,而且儲存數據的數組長度比較大。那么哈希沖突就比較少。否則沖突是很高的。

HashMap就是一個散列表,它是通過“拉鏈法”解決哈希沖突的

  • 什么是拉鏈法:
  • 拉鏈法又叫鏈地址法,拉鏈法就是把具有相同散列地址的關鍵字(同義詞)值放在同一個單鏈表中,稱為同義詞鏈表。有m個散列地址就有m個鏈表,同時用指針數組T[0..m-1]存放各個鏈表的頭指針,凡是散列地址為i的記錄都以結點方式插入到以T[i]為指針的單鏈表中。T中各分量的初值應為空指針.
  • 簡單來說拉鏈法就是數組加鏈表。
  • 大方向上,HashMap 里面是一個數組,然后數組中每個元素是一個單向鏈表。
    下圖中,每個綠色的實體是嵌套類 Entry 的實例,Entry 包含四個屬性:key, value, hash 值和用于單向鏈表的 next。
這個僅僅是示意圖,因為沒有考慮到數組要擴容的情況

從HashMap的實現來看,我們總結拉鏈法的實現步驟如下:
1. 計算 key 的 hashValue
2. 根據 hashValue 值定位到 table[hashIndex] 。( table[hashIndex] 是一條鏈表Node)
3. 若 table[hashValue] 為空則直接插入,不然則添加到鏈表末尾


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。