---------------------------------------------------------java
相信這個是你們最容易混淆的。安全
HashMap和Hashtable都實現了Map接口,但決定用哪個以前先要弄清楚它們之間的分別。主要的區別有:線程安全性,同步(synchronization),以及速度。多線程
HashMap
allows one null key and any number of null
values.,而Hashtable則不行)。這就是說,HashMap中若是在表中沒有發現搜索鍵,或者若是發現了搜索鍵,但它是一個空的值,那麼get()將返回null。若是有必要,用containKey()方法來區別這兩種狀況。要詳細瞭解ConcurrentHashMap見《構建一個更好的 HashMap---ConcurrentHashMap》框架
1) sychronized意味着在一次僅有一個線程可以更改Hashtable。就是說任何線程要更新Hashtable時要首先得到同步鎖,其它線程要等到同步鎖被釋放以後才能再次得到同步鎖更新Hashtable。源碼分析
2) Fail-safe和iterator迭代器相關。若是某個集合對象建立了Iterator或者ListIterator,而後其它的線程試圖「結構上」更改集合對象,將會拋出ConcurrentModificationException異常。但其它線程能夠經過set()方法更改集合對象是容許的,由於這並無從「結構上」更改集合。可是假如已經從結構上進行了更改,再調用set()方法,將會拋出IllegalArgumentException異常。性能
3) 結構上的更改指的是刪除或者插入一個元素,這樣會影響到map的結構。spa
---------------------------------------------------------.net
在分析他們的區別以前,咱們首先分別來簡單介紹一下他們倆。(後面我會詳細的結合源碼分析他倆)線程
HashSet實現了Set接口,它不容許集合中有重複的值,當咱們提到HashSet時,第一件事情就是在將對象存儲在HashSet以前,要先確保對象重寫equals()和hashCode()方法,這樣才能比較對象的值是否相等,以確保set中沒有儲存相等的對象。若是咱們沒有重寫這兩個方法,將會使用這個方法的默認實現。詳見《探索equals()和hashCode()方法》。code
public boolean add(Object o)方法用來在Set中添加元素,當元素值重複時則會當即返回false,若是成功添加的話會返回true。
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中。
*HashMap* | *HashSet* |
HashMap實現了Map接口 | HashSet實現了Set接口 |
HashMap儲存鍵值對 | HashSet僅僅存儲對象(且無重複對象) |
使用put()方法將元素放入map中 | 使用add()方法將元素放入set中 |
HashMap中使用鍵對象來計算hashcode值 | HashSet使用成員對象來計算hashcode值,對於兩個對象來講hashcode可能相同,因此equals()方法用來判斷對象的相等性,若是兩個對象不一樣的話,那麼返回false |
HashMap比較快,由於是使用惟一的鍵來獲取對象 | HashSet較HashMap來講比較慢 |