HashMap的hash()方法

基礎知識回顧

哈希算法

因爲Java的HashMap源碼裏面有個混淆函數hash(),我就想補一下哈希的定義。
哈希算法有以下三個特點

  • 安全,給定數據 M 容易算出哈希值 X ,而給定 X 不能算出 M ,或者說哈希算法應該是一個單向算法。
  • 兩個不同的數據,要擁有不相同的哈希。
  • 長度固定,給定一種哈希算法,不管輸入是多大的數據,輸出長度都是固定的。

仔細想一下,如果哈希的長度是固定的,也就是取值範圍是有限的,而輸入數據的取值範圍是無限的,所以總會找到兩個不同的輸入擁有相同的哈希。所以,哈希函數的安全性肯定是個相對概念。如果出現了兩個不同輸入有相同輸出的情況,就叫碰撞,collision 。不同的哈希算法,哈希位數越多,也就基本意味着安全級別越高,或者說它的”抗碰撞性“就越好。

位的操作

  • 正數的反碼=原碼=補碼
  • 負數的反碼爲符號位保持不變,其餘各位取反
  • 負數的補碼就是在補碼的基礎上+1
    在這裏插入圖片描述

邏輯運算符

  • >>>: 無符號右移

按二進制形式把所有的數字向右移動對應位數,低位移出(捨棄),高位的空位補零。對於正數來說和帶符號右移相同,對於負數來說不同。
其他結構和>>相似。

  • ^ : 位異或

0^0=0, 1^0=1, 0^1=1, 1^1=0

  • | : 或運算

0|0=0, 0|1=1, 1|0=1, 1|1=1

  • & : 與運算

0&0=0, 0&1=0, 1&0=0, 1&1=1

  • ~ : 非運算

~1=0, ~0=1

B樹 和 B+樹

B+樹主要底部的葉子節點,和相連的節點有鏈接指向的關係。回去還得翻一翻以前的Sqlserver的索引的知識。

HashMap的實現原理

源代碼主要通過數組+鏈表實現的,數組就是常說的桶,只是桶裏裝的是“糖葫蘆”式的鏈表,還是樹結構的數據。

hash()方法

這個擾動函數就是解決哈希出現相同key值的hash輸入的可能性。

  • 獲取key自帶的hashCode
  • h再進行無符號向右移動16位,也就是取h的高16位
  • 這樣的話自己的高半區和低半區做異或,就是爲了混合原始哈希碼的高位和低位,以此來加大低位的隨機性。
static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章