hashMap與hashTable區別

1.HashTable

• 底層數組+鏈表實現,無論key還是value都不能爲null,線程安全,實現線程安全的方式是在修改數據時鎖住整個HashTable,效率低,ConcurrentHashMap做了相關優化
• 初始size爲11,擴容:newsize = olesize*2+1
• 計算index的方法:index = (hash & 0x7FFFFFFF) % tab.length

2.HashMap

• 底層數組+鏈表實現,可以存儲null鍵和null值,線程不安全
• 初始size爲16,擴容:newsize = oldsize*2,size一定爲2的n次冪
• 擴容針對整個Map,每次擴容時,原來數組中的元素依次重新計算存放位置,並重新插入
• 插入元素後才判斷該不該擴容,有可能無效擴容(插入後如果擴容,如果沒有再次插入,就會產生無效擴容)
• 當Map中元素總數超過Entry數組的75%,觸發擴容操作,爲了減少鏈表長度,元素分配更均勻
計算index方法:index = hash & (tab.length – 1)

3.ConcurrentHashMap

• 底層採用分段的數組+鏈表實現,線程安全
• 通過把整個Map分爲N個Segment,可以提供相同的線程安全,但是效率提升N倍,默認提升16倍。(讀操作不加鎖,由於HashEntry的value變量是 volatile的,也能保證讀取到最新的值。)
• Hashtable的synchronized是針對整張Hash表的,即每次鎖住整張表讓線程獨佔,ConcurrentHashMap允許多個修改操作併發進行,其關鍵在於使用了鎖分離技術
• 有些方法需要跨段,比如size()和containsValue(),它們可能需要鎖定整個表而而不僅僅是某個段,這需要按順序鎖定所有段,操作完畢後,又按順序釋放所有段的鎖
• 擴容:段內擴容(段內元素超過該段對應Entry數組長度的75%觸發擴容,不會對整個Map進行擴容),插入前檢測需不需要擴容,有效避免無效擴容

HashTable與HashMap的區別

1.HashMap不是線程安全的,HashTable是線程安全的一個Collection。

2.HashMap允許將null作爲一個entry的key或者value,而Hashtable不允許。

3.HashMap是一個接口 是map接口的子接口,是將鍵映射到值的對象,其中鍵和值都是對象,並且不能包含重複鍵,但可以包含重複值。

4.HashMap允許null key和null value,而hashtable不允許。

5.HashMap是Hashtable的輕量級實現(非線程安全的實現),他們都完成了Map接口,主要區別在於HashMap允許空(null)鍵值(key),由於非線程安全,效率上可能高於Hashtable。HashMap允許將null作爲一個entry的key或者value,而Hashtable不允許。

6.HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因爲contains方法容易讓人引起誤解。

7.Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現。

8.最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個線程訪問

9.Hashtable時,不需要自己爲它的方法實現同步,而HashMap 就必須爲之提供外同步。

10.Hashtable和HashMap採用的hash/rehash算法都大概一樣,所以性能不會有很大的差異。

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