HashMap和Hashtable的詳細區別
阿新 • • 發佈:2019-01-25
HashMap和Hashtable的區別
- 兩者最主要的區別在於Hashtable是執行緒安全,而HashMap則非執行緒安全。Hashtable的實現方法裡面都添加了synchronized關鍵字來確保執行緒同步,因此相對而言HashMap效能會高一些,我們平時使用時若無特殊需求建議使用HashMap,在多執行緒環境下若使用HashMap需要使用Collections.synchronizedMap()方法來獲取一個執行緒安全的集合(Collections.synchronizedMap()實現原理是Collections定義了一個SynchronizedMap的內部類,這個類實現了Map介面,在呼叫方法時使用synchronized來保證執行緒同步,當然了實際上操作的還是我們傳入的HashMap例項,簡單的說就是Collections.synchronizedMap()方法幫我們在操作HashMap時自動添加了synchronized來實現執行緒同步,類似的其它Collections.synchronizedXX方法也是類似原理。
- HashMap可以使用null作為key,不過建議還是儘量避免這樣使用。HashMap以null作為key時,總是儲存在table陣列的第一個節點上。而Hashtable則不允許null作為key。
- HashMap繼承了AbstractMap,HashTable繼承Dictionary抽象類,兩者均實現Map介面。
- HashMap的初始容量為16,Hashtable初始容量為11,兩者的填充因子預設都是0.75。
- HashMap擴容時是當前容量翻倍即:capacity*2,Hashtable擴容時是容量翻倍+1即:capacity*2+1。
- HashMap和Hashtable的底層實現都是陣列+連結串列結構實現。
- 兩者計算hash的方法不同:
Hashtable計算hash是直接使用key的hashcode對table陣列的長度直接進行取模:
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
HashMap計算hash對key的hashcode進行了二次hash,以獲得更好的雜湊值,然後對table陣列長度取摸:
static int hash(int h) {
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
static int indexFor(int h, int length) {
return h & (length-1);
}
7.判斷是否含有某個鍵
在HashMap 中,null 可以作為鍵,這樣的鍵只有一個;可以有一個或多個鍵所對
應的值為null。當get()方法返回null 值時,既可以表示HashMap 中沒有該鍵,也可
以表示該鍵所對應的值為null。因此,在HashMap 中不能用get()方法來判斷HashM
ap 中是否存在某個鍵,而應該用containsKey()方法來判斷。Hashtable 的鍵值都不能
為null,所以可以用get()方法來判斷是否含有某個鍵。