淺談HashMap(1)

Java爲數據結構中的映射定義了一個接口java.util.Map,然後HashMap是這個接口其中的一個實現類 他的內部實現在java1.7及之前是一種叫鏈表散列的數據結構,也就是數組加鏈表的數據結構實現的

 

當調用Put方法存值時,會先調用hashcode方法計算出key的哈希值,然後將keyvalue放入這個哈希值對應的數組下的鏈表中.HashMap允許一條記錄的鍵爲null,允許多條記錄的值爲null,因爲在計算哈希值時,會先判斷key是否爲Null,如果爲null 就將數據放入map的首位)

當調用get方法取值時 會根據key值計算出hashcode去查找對應的數組,然後在數組中再根據key值查詢對應的value

簡單來說 哈希算法可以將數據分到一排哈希桶中,將哈希值相同的數據放到同一個

哈希桶,如果倆個對象相同 hash值肯定相同,但是hash值相同倆個對象不一定相同 比如”Ea”和”FB” hash值相同,但是對象不同

1.爲什麼HashMap能保證Key的唯一性?

因爲HashMapput存數據時會先通過keyhash值找到數據在哪個數組元素對應的鏈表中,然後遍歷鏈表找到key值對應的value,如果已經有值就進行修改,這樣就使key值變爲了唯一的(自定義對象需要重寫hashCodeEquals方法)

爲什麼要重寫hashCode方法:因爲在默認的情況下hashCode方法是將對象的存儲地址進行映射,當新建倆個自定義對象時不同的對象存儲地址肯定不同,所以所得的hashCode值也肯定不同

爲什麼要重寫equals方法:因爲要判斷兩個對象在邏輯上是否相等,需要根據類的成員變量來判斷兩個類的實例是否相等,而繼承Object中的equals方法只能判斷兩個引用變量是否是同一個對象

2.爲什麼HashMap需要使用哈希算法?

因爲效率.如果每增加一個元素就檢查一次,那麼當元素很多時,後添加到集合中的元素比較的次數就非常多了。也就是說,如果集合中現在已經有1000個元素,那麼第1001個元素加入集合時,它就要調用1000equals方法。這顯然會大大降低效率。計算哈希值相當於計算索引,通過索引去存取值可以大大的加快運算的效率 因爲實際調用equals方法的次數就大大降低了,幾乎只需要一兩次

 

 

拓展:

Hashmap,HashTable,LinkedHashMap,TreeMap

(1) HashMap:它根據鍵的hashCode值存儲數據,大多數情況下可以直接定位到它的值,因而具有很快的訪問速度,但遍歷順序卻是不確定的。 HashMap最多隻允許一條記錄的鍵爲null,允許多條記錄的值爲nullHashMap非線程安全,即任一時刻可以有多個線程同時寫HashMap,可能會導致數據的不一致。如果需要滿足線程安全,可以用 CollectionssynchronizedMap方法使HashMap具有線程安全的能力,或者使用ConcurrentHashMap

(2) HashtableHashtable是遺留類,很多映射的常用功能與HashMap類似,不同的是它承自Dictionary類,並且是線程安全的,任一時間只有一個線程能寫Hashtable,併發性不如ConcurrentHashMap,因爲ConcurrentHashMap引入了分段鎖。Hashtable不建議在新代碼中使用,不需要線程安全的場合可以用HashMap替換,需要線程安全的場合可以用ConcurrentHashMap替換。

(3) LinkedHashMapLinkedHashMapHashMap的一個子類,保存了記錄的插入順序,在用Iterator遍歷LinkedHashMap時,先得到的記錄肯定是先插入的,也可以在構造時帶參數,按照訪問次序排序。

(4) TreeMapTreeMap實現SortedMap接口,能夠把它保存的記錄根據鍵排序,默認是按鍵值的升序排序,也可以指定排序的比較器,當用Iterator遍歷TreeMap時,得到的記錄是排過序的。如果使用排序的映射,建議使用TreeMap。在使用TreeMap時,key必須實現Comparable接口或者在構造TreeMap傳入自定義的Comparator,否則會在運行時拋出java.lang.ClassCastException類型的異常。

對於上述四種Map類型的類,要求映射中的key是不可變對象。不可變對象是該對象在創建後它的哈希值不會被改變。如果對象的哈希值發生變化,Map對象很可能就定位不到映射的位置了。

 

-----------------------------------------------------------------------------------------------------------------------------

Java 1.8數組+鏈表+紅黑樹

當鏈表長度大於默認值8,就會默認轉換爲紅黑樹 增加HashMap的性能

-----------------------------------------------------------------------------------------------------------------------------

 

ConcurrentHashMap(king可瑞特) 分段鎖

對數據使用分段加載同步鎖,默認可以同時併發16個線程去同時操作數據,相比Hashtable的同步併發量更高,效率也更快

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章