1. 程式人生 > >2018/6/29 關於hashmap的總結

2018/6/29 關於hashmap的總結

可能 函數 對比 組元 散列 完美 內部 round 什麽是

  1. hashMap和ConcurrentHashMap的區別
  2. hashMap內部具體如何實現的
  3. 如果hashMap的key是一個自定義的類,怎麽辦
  4. 為什麽重寫equals還要重寫hashcode

一、什麽是hashmap

  在討論哈希表之前,我們要先大概了解一下其他數據結構在新增、查找等基礎操作執行性能

  數組:采用一段連續的存儲單元來存儲數據。對於指定下標的查找,時間復雜度為O(1);通過給定值進行查找,需要遍歷數組,逐一對比給定關鍵字和數組元素,時間復雜度為O(n),當然對於有序數組,則可以采用二分查找,插值查找,斐波那契查找等方式,可將查找復雜度提高為O(logn);對於一般的插入刪除操作,涉及到數據元素的移動,其平均復雜度為O(n)。

  線性鏈表:對於鏈表的新增,刪除等操作(在找到指定操作位置後),僅需處理結點間的引用即可,時間復雜度為O(1),而查找操作需要遍歷鏈表逐一進行比對,復雜度為O(n)

  二叉樹:對一棵相對平衡的有序二叉樹,對其進行插入,查找,刪除等操作,平均復雜度均為O(logn)。

 哈希表:相比上述幾種數據結構,在哈希表中進行添加,刪除,查找等操作,性能十分之高,不考慮哈希沖突的情況下,僅需一次定位即可完成,時間復雜度為O(1),接下來我們就來看看哈希表是如何實現達到驚艷的常數階O(1)的。

  我們知道,數據結構的物理存儲結構只有兩種:順序存儲結構鏈式存儲結構(像棧,隊列,樹,圖等是從邏輯結構去抽象的,映射到內存中,也這兩種物理組織形式),而在上面我們提到過,在數組中根據下標查找某個元素,一次定位就可以達到,哈希表利用了這種特性,哈希表的主幹就是數組

  比如我們要新增或查找某個元素,我們通過把當前元素的關鍵字 通過某個函數映射到數組中的某個位置,通過數組下標一次定位就可完成操作。

        存儲位置 = f(關鍵字)

  其中,這個函數f一般稱為哈希函數,這個函數的設計好壞會直接影響到哈希表的優劣。舉個例子,比如我們要在哈希表中執行插入操作:

  技術分享圖片

  查找操作同理,先通過哈希函數計算出實際存儲地址,然後從數組中對應地址取出即可。

  哈希沖突

  然而萬事無完美,如果兩個不同的元素,通過哈希函數得出的實際存儲地址相同怎麽辦?也就是說,當我們對某個元素進行哈希運算,得到一個存儲地址,然後要進行插入的時候,發現已經被其他元素占用了,其實這就是所謂的哈希沖突

,也叫哈希碰撞。前面我們提到過,哈希函數的設計至關重要,好的哈希函數會盡可能地保證 計算簡單散列地址分布均勻,但是,我們需要清楚的是,數組是一塊連續的固定長度的內存空間,再好的哈希函數也不能保證得到的存儲地址絕對不發生沖突。那麽哈希沖突如何解決呢?哈希沖突的解決方案有多種:開放定址法(發生沖突,繼續尋找下一塊未被占用的存儲地址),再散列函數法,鏈地址法,而HashMap即是采用了鏈地址法,也就是數組+鏈表的方式,

2018/6/29 關於hashmap的總結