HashMap和HashTable的選擇

關於編程中HashMap和HashTable的選擇問題,我們可以先看看下面這些問題。

歷史問題

Hashtable是個過時的集合類,是基於陳舊的Dictionary類的,並且存在於Java API中很久了。在Java 4中被重寫了,實現了Map接口,所以自此以後也成了Java集合框架中的一部分,而HashMap是Java 1.2引進的Map接口的一個實現。

同步問題

HashMap是非synchronized,而Hashtable是synchronized,這意味着Hashtable是線程安全的,多個線程可以共享一個Hashtable;而如果沒有正確的同步的話,多個線程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的擴展性更好。

迭代問題

HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以當有其它線程改變了HashMap的結構(增加或者移除元素),將會拋出ConcurrentModificationException,但迭代器本身的remove()方法移除元素則不會拋出ConcurrentModificationException異常。但這並不是一個一定發生的行爲,要看JVM。這條同樣也是Enumeration和Iterator的區別。

key值問題

HashMap可以讓你將空值作爲一個表的條目的key或value。HashMap中只有一條記錄可以是一個空的key,但任意數量的條目可以是空的value。這就是說,如果在表中沒有發現搜索鍵,或者如果發現了搜索鍵,但它是一個空的值,那麼get()將返回null。如果有必要,用containKey()方法來區別這兩種情況。

效率問題

由於Hashtable是線程安全的也是synchronized,所以在單線程環境下它比HashMap要慢。如果你不需要同步,只需要單一線程,那麼使用HashMap性能要好過Hashtable。

元素順序

HashMap不能保證隨着時間的推移Map中的元素次序是不變的。

HashMap同步

HashMap可以通過下面的語句進行同步:
Map m = Collections.synchronizeMap(hashMap);

術語解釋

sychronized

sychronized意味着在一次僅有一個線程能夠更改Hashtable。就是說任何線程要更新Hashtable時要首先獲得同步鎖,其它線程要等到同步鎖被釋放之後才能再次獲得同步鎖更新Hashtable。

fail-fast and fail-safe

關於fail-fast and fail-safe,可以參考這篇文章Fail Fast vs Fail Safe

總結

在目前的編程中基本上可以不用HashTable了,在不要求線程安全的情況下直接使用HashMap,效率比較高;如果,要求線程安全,則使用ConcurrentHashMap來代替HashMap。

參考

發佈了97 篇原創文章 · 獲贊 125 · 訪問量 30萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章