hash演算法實現-(java-hashmap)

來源:互聯網
上載者:User
Hash又叫散列,輸入任意長度的位元組,通過雜湊演算法,轉換成固定長度的雜湊值;

雜湊列表的實現是通過對key進行雜湊,得到的雜湊值來做為儲存資料的數組的索引,這樣會有一個問題是不同的key的雜湊值有可能會重複,所以我們在數組儲存位上建立一個鏈表來儲存相同雜湊值的資料

在java中就是通過引用,數組,鏈表來實現的hashmap

我們先看hashmap中存放資料的結構:

static class Entry<K,V> implements Map.Entry<K,V> {         final K key;          V value;          final int hash;          Entry<K,V> next;  ...........  } 

 

每個Entry會有一個指向下一個資料的引用,這就在同一個槽位上構成了鏈表,最先加入的放在鏈表頭部,後加入的放在尾部。

很顯然只有當我們能夠均勻的將hash值分布在數組的所有槽位上的時候,這個時候我們對鏈表操作是最少的,效率是最高的。

基本的hash定址演算法有除法散列法平方散列法斐波那契(Fibonacci)散列法等,但是java是這樣做的:

 static int indexFor(int h, int length) {        return h & (length-1);    }

 

java會用key的hashcode值與數組的槽數-1進行與運算

這裡會有一個問題只有當數組的槽數為2的n次方-1,其二進位全是1的(如2的2次方-1=11)的時候雜湊值產生碰撞的機率是最小的

所以在java中hashmap的數組的初始大小是16(2的4次方)

 

hashmap的resize:

當不斷put資料使資料慢慢變大的時候,剛開始的數組已經不能滿足需求了,我們需要擴大數組的槽數

hashmap中有loadFactor屬性,該屬性預設為0.75,即元素個數達到數組的百分之七十五的時候,數組槽數會進行翻倍,並且之前已存入的資料會重新進行計算。

 

so:如果我們可以預估我們會在hashmap中存放1000個資料,那麼我們就要確保數組的槽數乘上0.75大於1000,我們得到1366,如果我們這樣寫new HashMap(1366),java會自動幫我們轉換成new HashMap(2048)(2的n次方)

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.