Map(映射)

散列表介紹:數組

數組和鏈表均可以是有序的(即存儲順序與取出順序一致),但這樣是有代價的,須要遍歷才能夠尋找某一特定元素;函數

而還有另外的一些存儲結構:不在乎元素的順序,可以快速的查找元素的數據spa

其中就有一種很是常見的:散列表設計

2.1散列表工做原理

散列表爲每一個對象計算出一個整數,稱爲散列碼根據這些計算出來的整數(散列碼)保存在對應的位置上3d

在Java中,散列表用的是鏈表數組實現的每一個列表稱之爲桶。code

一個桶上可能會遇到被佔用的狀況(hashCode散列碼相同,就存儲在同一個位置上),這種狀況是沒法避免的,這種現象稱之爲:散列衝突對象

  • 此時須要用該對象與桶上的對象進行比較,看看該對象是否存在桶子上了~若是存在,就不添加了,若是不存在則添加到桶子上
  • 固然了,若是hashcode函數設計得足夠好,桶的數目也足夠,這種比較是不多的~
  • JDK1.8中,桶滿時會從鏈表變成平衡二叉樹

若是散列表太滿,是須要對散列表再散列,建立一個桶數更多的散列表,並將原有的元素插入到新表中,丟棄原來的表~blog

  • 裝填因子(load factor)決定了什麼時候對散列表再散列~
  • 裝填因子默認爲0.75,若是表中超過了75%的位置已經填入了元素,那麼這個表就會用雙倍的桶數自動進行再散列

平衡樹:知足平衡條件的樹排序

AVL樹,帶有平衡條件的二叉排序樹(平衡條件:每一個節點的左子樹和右子樹的高度最多差 1);索引

紅黑樹

在2-3樹的理論基礎上發明了紅黑樹(2-3-4樹也是一樣的道理,只是2-3樹是最簡單的一種狀況,因此我就不說2-3-4樹了)。

紅黑樹是對2-3查找樹的改進,它能用一種統一的方式完成全部變換

紅黑樹用的是也是兩種方式來替代2-3樹不斷的節點交換操做:

  • 旋轉:順時針旋轉和逆時針旋轉
  • 反色:交換紅黑的顏色
  • 這個兩個實現比2-3樹交換的節點(合併,分解)要方便一些

紅黑樹爲了保持平衡,還有制定一些約束,遵照這些約束的才能叫作紅黑樹:

  1. 紅黑樹是二叉搜索樹。
  2. 根節點是黑色
  3. 每一個葉子節點都是黑色的空節點(NIL節點)
  4. 每一個紅色節點的兩個子節點都是黑色。(從每一個葉子到根的全部路徑上不能有兩個連續的紅色節點)
  5. 從任一節點到其每一個葉子的全部路徑都包含相同數目的黑色節點(每一條樹鏈上的黑色節點數量(稱之爲「黑高」)必須相等)
  6. HashMap剖析

  7. 咱們知道Hash存儲的底層是散列表,而在Java中散列表的實現是經過數組+鏈表的~我

  8. 咱們能夠簡單總結出HashMap:

    • 無序,容許爲null,非同步
    • 底層由散列表(哈希表)實現
    • 初始容量和裝載因子對HashMap影響挺大的,設置小了很差,設置大了也很差
      • 根據hash值肯定key在數組中的索引:
      • 咱們是根據key的哈希值來保存在散列表中的,咱們表默認的初始容量是16,要放到散列表中,就是0-15的位置上。也就是tab[i = (n - 1) & hash]。能夠發現的是:在作&運算的時候,僅僅是後4位有效~那若是咱們key的哈希值高位變化很大,低位變化很小。直接拿過去作&運算,這就會致使計算出來的Hash值相同的不少。

        而設計者將key的哈希值的高位也作了運算(與高16位作異或運算,使得在作&運算時,此時的低位其實是高位與低位的結合),這就增長了隨機性,減小了碰撞衝突的可能性!

    • put方法能夠說是HashMap的核心,咱們來看看:
相關文章
相關標籤/搜索