2018/6/29 關於hashmap的總結
- hashMap和ConcurrentHashMap的區別
- hashMap內部具體如何實現的
- 如果hashMap的key是一個自定義的類,怎麽辦
- 為什麽重寫equals還要重寫hashcode
一、什麽是hashmap
在討論哈希表之前,我們要先大概了解一下其他數據結構在新增、查找等基礎操作執行性能
數組:采用一段連續的存儲單元來存儲數據。對於指定下標的查找,時間復雜度為O(1);通過給定值進行查找,需要遍歷數組,逐一對比給定關鍵字和數組元素,時間復雜度為O(n),當然對於有序數組,則可以采用二分查找,插值查找,斐波那契查找等方式,可將查找復雜度提高為O(logn);對於一般的插入刪除操作,涉及到數據元素的移動,其平均復雜度為O(n)。
線性鏈表:對於鏈表的新增,刪除等操作(在找到指定操作位置後),僅需處理結點間的引用即可,時間復雜度為O(1),而查找操作需要遍歷鏈表逐一進行比對,復雜度為O(n)
二叉樹:對一棵相對平衡的有序二叉樹,對其進行插入,查找,刪除等操作,平均復雜度均為O(logn)。
哈希表:相比上述幾種數據結構,在哈希表中進行添加,刪除,查找等操作,性能十分之高,不考慮哈希沖突的情況下,僅需一次定位即可完成,時間復雜度為O(1),接下來我們就來看看哈希表是如何實現達到驚艷的常數階O(1)的。
我們知道,數據結構的物理存儲結構只有兩種:順序存儲結構和鏈式存儲結構(像棧,隊列,樹,圖等是從邏輯結構去抽象的,映射到內存中,也這兩種物理組織形式),而在上面我們提到過,在數組中根據下標查找某個元素,一次定位就可以達到,哈希表利用了這種特性,哈希表的主幹就是數組
比如我們要新增或查找某個元素,我們通過把當前元素的關鍵字 通過某個函數映射到數組中的某個位置,通過數組下標一次定位就可完成操作。
存儲位置 = f(關鍵字)
其中,這個函數f一般稱為哈希函數,這個函數的設計好壞會直接影響到哈希表的優劣。舉個例子,比如我們要在哈希表中執行插入操作:
查找操作同理,先通過哈希函數計算出實際存儲地址,然後從數組中對應地址取出即可。
哈希沖突
然而萬事無完美,如果兩個不同的元素,通過哈希函數得出的實際存儲地址相同怎麽辦?也就是說,當我們對某個元素進行哈希運算,得到一個存儲地址,然後要進行插入的時候,發現已經被其他元素占用了,其實這就是所謂的哈希沖突
2018/6/29 關於hashmap的總結