HashMap vs HashTable

HashMap 與 HashTable 的差異?能不能讓HashMap同步?

HashMap和HashTable之間的差異在Java面試中經常被提問到,以此來檢驗面試者是否正確理解容器類的用法以及是否知道怎麼做出選擇。HashTable是一個遺留的容器類,存在於Java API中很長時間了,並且在Java4的時候被重構了,從那時起,HashTable成爲了Java集合框架(Java Collections framework)的一部分。在Java中,HashMap VS HashTable是非常流行的問題,以至於可以排到Java集合面試問題題的前幾名。在接下來的這篇Java文章中,我們不僅將研究它們兩者的差異,還將探索它們之間的共性,先來看一下兩者的差異。


HashMap 與 HashTable 的差異

兩者都實現了Map接口,但是它們有一些重大的區別,在決定使用HashMap還是HashTable的時候知道這些區別是非常重要的。區別包括:線程安全、同步、速度,以下是詳細敘述:

1. HashMap類大體上和HashTable相同,但是HashMap不是同步的,並且HashMap允許null值(HashMap允許key或者value的值爲null,但是HashTable中不可以)。


2. 兩者之間最重要的差異就是HashMap是非同步的,而HashTable是同步的,這就意味着HashTable是線程安全的,可以被多個線程共享;而HashMap在沒有被恰當的同步之前是不能夠被多個線程共享的。在Java5中引入了ConcurrentHashMap作爲一種可選擇的替代,並且比HashTable提供了更好的可擴展性。


3. HashMap vs HashTable的另外一個重要的區別是在HashMap中它的迭代器是快速失敗的(fail-fast),並且在發生結構性修改的時候會立即拋出ConcurrentModificationExeception異常。而在HashTable中這些是不會發生的。但是這並不是一個獲得保證的行爲,因爲這個行爲是JVM儘量去執行的。(注:通過閱讀HashMap的源碼可以發現,HashMap保存一個叫做modCount的值,每一次結構性修改的時候都會自增modCount的值,然後在迭代的時候,modCount會對迭代行爲產生影響)


4. 另一個需要留意的區別就是因爲保證線程安全和同步的實施,HashTable相比於HashMap是非常的慢的,假如在單線程的環境中或者不需要同步,應該考慮使用HashMap。


5. HashMap不保證元素在map中的映射順序隨着時間的改變是不變的。(因爲隨着容量的最大,會發生rehashing操作)


一些重要的術語

1)同步(Synchronized)意味着在同一個時間只能有一個線程修改哈希表。更進一步的說,這就意味着任何一個線程想要在哈希表上實施update操作之前,都必須先獲得這個對象的鎖,然後其他的對象必須等待它完成之後釋放鎖後才能修改。


2)快速失敗(fail-fast)是與迭代器有關的內容。假如一個迭代器被創建出來迭代容器內的元素,而另外的一個線程隨即對這個容器進行了結構性的修改,那麼就會立即拋出    ConcurrentModificationExeception異常。其他線程對容器的非結構性修改則不會導致該異常的發生。


3)結構性修改是指刪除或者插入元素、改變底層數組的大小使得map的結構發生變化,而僅僅對於map的value做出修改,則不算結構性修改。


如何使HashMap同步?

可以公共下面的方法使HashMap同步

Map m = Collections.synchronizeMap(hashMap);



---文章翻譯於 : Difference between HashMap and HashTable? Can we make hashmap synchronized?




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