學習hashMap

         基於java 1.6前端

         HashMap和其餘的Map同樣,都有由key和它的value構成。可是不一樣的Map其key的存儲方式是大不相同的。HashMap較其餘Map具備更好的查詢效率,這是因爲HashMap採用了Hash算法。每個key自己都具備一個獲取hashCode的方法。這些hashCode經過hash算法,被轉化爲一個個序號,對應「橫向」鏈表上的存儲位置。java

         當序號相同且key的值不一樣時,在這個位置上就會造成一個「縱向」的鏈表。在這個鏈表中先添加的key處於鏈表的末端,後添加的處於鏈表的前端。鏈表的存儲單元爲 Entry<k,y> ,在這個類中有一個還有一個類型爲Entry<k,y>的參數,名爲nextnext指向的是下一個Entry<k,y>的地址,HashMap就是以這樣的方式造成了一個「縱向」的鏈表。 算法


       hashMap還具備自動擴張的功能。每當map中的容量達到threshold的時候,hashMap就會經過resize()方法擴張一倍。Resize()的過程是比較消耗性能的,因此若是事先知道存儲的大概範圍時,也能夠預先設置Map的大小,從而下降擴張帶來的消耗。threshold的算法是size*loadFactor,loadFactor是一個比例參數,決定了多大比例的長度做爲threshold,通常而言loadFactor的值爲0.75。若是一個hashMap的長度爲16loadFactor的值爲0.75,那麼它的臨界值爲12,當添加的元素達到12時,這個map就會擴張一倍達到32.
數組


hashMap能夠經過構造函數在初始化的時候設置hashMap的各項參數。它提供的構造參數有HashMap(int size,float threshold)HashMap(int size),HashMap() HashMap(Map map)。size是指Map的大小,然而這個值不必定會成爲HashMap的最終大小,它會最終轉換爲最接近 2的N次方值。在HashMap(int size,float threshold)的源碼裏,有這樣的代碼:函數

       其中j爲最終的大小,i就是咱們傳遞過來的size,經過位運算,j的最終取值爲稍大於size的2的N次方值。如下是默認的構造函數HashMap():性能

       能夠看到loadFactor的默認值爲0.75,默認臨界值爲12(並非很大),而「橫向」的鏈表其實只是一個數組。若是事先知道HashMap的大小,就應該使用HashMap(int size,float loadFactor)或HashMap(int size)爲這個HashMap設置一個合適的大小。即使HashMap有着自動擴張的能力,可是這個功能會消耗很多性能,因此事先設置長度是更好的辦法。spa


       hashMap的大小老是2n次方。這是通過計算得出的最佳大小,在這個大小上,hashCode的映射能夠達到最小碰撞的效果。
blog

      1.將key的hashCode通過HashMap的hash算法後獲取的值設爲A文檔

      2.將HashMap的總長度設爲Sget

那麼這個key對應的hashMap中的位置實際應爲table[A & (S-1)] 。若是總長度總爲16,那麼在16-1在二進制對應的值爲1111,這個值具備最好的匹配度,由於它每一位都爲1。它就像一面光滑的鏡子,能夠將Hash後的值均勻的映射到table的各個位置上。

參考文檔:

http://alex09.iteye.com/blog/539545

http://www.iteye.com/topic/539465/

相關文章
相關標籤/搜索