HashTable,HashMap和HashSet比較

 

1. HashTable和HashMap的區別

---------------------------------------------------------java

相信這個是你們最容易混淆的。安全

 

HashMap和Hashtable都實現了Map接口,但決定用哪個以前先要弄清楚它們之間的分別。主要的區別有:線程安全性同步(synchronization),以及速度多線程

  1. HashMap幾乎能夠等價於Hashtable,除了HashMap是非synchronized的,並能夠接受null(HashMap allows one null key and any number of null values.,而Hashtable則不行)。這就是說,HashMap中若是在表中沒有發現搜索鍵,或者若是發現了搜索鍵,但它是一個空的值,那麼get()將返回null。若是有必要,用containKey()方法來區別這兩種狀況。
  2. HashMap是非synchronized,而Hashtable是synchronized,這意味着Hashtable是線程安全的,多個線程能夠共享一個Hashtable;而若是沒有正確的同步的話,多個線程是不能共享HashMa的。 便是說,在多線程應用程序中,不用專門的操做就安全地可使用Hashtable了;而對於HashMap,則須要額外的同步機制。但HashMap的同步問題可經過Collections的一個靜態方法獲得解決:
                Map Collections.synchronizedMap(Map m)
    這個方法返回一個同步的Map,這個Map封裝了底層的HashMap的全部方法,使得底層的HashMap即便是在多線程的環境中也是安全的。                                                                                              而並且
    Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的擴展性更好。

    要詳細瞭解ConcurrentHashMap見《構建一個更好的 HashMap---ConcurrentHashMap框架

  1. 另外一個區別是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。因此當有其它線程改變了HashMap的結構(增長或者移除元素),將會拋出ConcurrentModificationException,但迭代器自己的remove()方法移除元素則不會拋出ConcurrentModificationException異常。但這並非一個必定發生的行爲,要看JVM。這條一樣也是Enumeration和Iterator的區別。
  2. 因爲Hashtable是線程安全的也是synchronized,因此在單線程環境下它比HashMap要慢。若是你不須要同步,只須要單一線程,那麼使用HashMap性能要好過Hashtable。
  3. HashMap不能保證隨着時間的推移Map中的元素次序是不變的。
  4. 哈希值的使用不一樣,HashTable直接使用對象的hashCode,代碼是這樣的:
          int hash = key.hashCode();
          int index = (hash & 0x7FFFFFFF) % tab.length;
    而HashMap從新計算hash值,並且用與代替求模:
    int hash = hash(k);
    int i = indexFor(hash, table.length);

 

 

要注意的一些重要術語:

1) sychronized意味着在一次僅有一個線程可以更改Hashtable。就是說任何線程要更新Hashtable時要首先得到同步鎖,其它線程要等到同步鎖被釋放以後才能再次得到同步鎖更新Hashtable。源碼分析

2) Fail-safe和iterator迭代器相關。若是某個集合對象建立了Iterator或者ListIterator,而後其它的線程試圖「結構上」更改集合對象,將會拋出ConcurrentModificationException異常。但其它線程能夠經過set()方法更改集合對象是容許的,由於這並無從「結構上」更改集合。可是假如已經從結構上進行了更改,再調用set()方法,將會拋出IllegalArgumentException異常。性能

3) 結構上的更改指的是刪除或者插入一個元素,這樣會影響到map的結構。spa

 

2. HashSet和HashMap的區別

---------------------------------------------------------.net

在分析他們的區別以前,咱們首先分別來簡單介紹一下他們倆。(後面我會詳細的結合源碼分析他倆)線程

 

什麼是HashSet?

 

HashSet實現了Set接口,它不容許集合中有重複的值,當咱們提到HashSet時,第一件事情就是在將對象存儲在HashSet以前,要先確保對象重寫equals()和hashCode()方法,這樣才能比較對象的值是否相等,以確保set中沒有儲存相等的對象。若是咱們沒有重寫這兩個方法,將會使用這個方法的默認實現。詳見《探索equals()和hashCode()方法》。code

public boolean add(Object o)方法用來在Set中添加元素,當元素值重複時則會當即返回false,若是成功添加的話會返回true。

 

什麼是HashMap?

HashMap實現了Map接口,Map接口對鍵值對進行映射。Map中不容許重複的鍵。Map接口有兩個基本的實現,HashMap和TreeMap。TreeMap保存了對象的排列次序,而HashMap則不能。HashMap容許鍵和值爲null。HashMap是非synchronized的,但collection框架提供方法能保證HashMap synchronized,這樣多個線程同時訪問HashMap時,能保證只有一個線程更改Map。

public Object put(Object Key,Object value)方法用來將元素添加到map中。

HashSet和HashMap的區別

*HashMap* *HashSet*
HashMap實現了Map接口 HashSet實現了Set接口
HashMap儲存鍵值對 HashSet僅僅存儲對象(且無重複對象)
使用put()方法將元素放入map中 使用add()方法將元素放入set中
HashMap中使用鍵對象來計算hashcode值 HashSet使用成員對象來計算hashcode值,對於兩個對象來講hashcode可能相同,因此equals()方法用來判斷對象的相等性,若是兩個對象不一樣的話,那麼返回false
HashMap比較快,由於是使用惟一的鍵來獲取對象 HashSet較HashMap來講比較慢
相關文章
相關標籤/搜索