HashMap与HashTable联系与区别
HashMap與HashTable
1.hashMap去掉了HashTable 的contains方法,但是加上了containsValue()和containsKey()方法。
2.hashTable同步的,而HashMap是非同步的,效率上比hashTable要高,HashMap不是線程安全的 ,HashTable是線程安全的一個Collection。
3.hashMap允許空鍵值,而hashTable不允許。
ashtable繼承自Dictionary類,而HashMap是Map接口的一個實現。這里要說明一下Dictionary類是jdk1.0中就有的,而Map接口是1.2之后才有的,當然與此同時Hashtable也實現了Map接口。
HashTable的應用非常廣泛,HashMap是新框架中用來代替HashTable的類,也就是說建議使用HashMap,不要使用HashTable。可能你覺得HashTable很好用,為什么不用呢?這里簡單分析他們的區別。
1.HashTable的方法是同步的,HashMap未經同步,所以在多線程場合要手動同步HashMap這個區別就像Vector和ArrayList一樣。
2.HashTable不允許null值(key和value都不可以),HashMap允許null值(key和value都可以)。
3.HashTable有一個contains(Object value),功能和containsValue(Object value)功能一樣。
4.HashTable使用Enumeration,HashMap使用Iterator。
以上只是表面的不同,它們的實現也有很大的不同。
5.HashTable中hash數組默認大小是11,增加的方式是 old*2+1。HashMap中hash數組的默認大小是16,而且一定是2的指數。
6.哈希值的使用不同,HashTable直接使用對象的hashCode,代碼是這樣的:
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
而HashMap重新計算hash值,而且用與代替求模:
int hash = hash(k);
int i = indexFor(hash, table.length);
?
static int hash(Object x) {
int h = x.hashCode();
?
h += ~(h << 9);
h ^= (h >>> 14);
h += (h << 4);
h ^= (h >>> 10);
return h;
}
static int indexFor(int h, int length) {
return h & (length-1);
}
?
HashMap和Hashtable的相同點
HashMap和Hashtable都是存儲“鍵值對(key-value)”的散列表,而且都是采用拉鏈法實現的。
存儲的思想都是:通過table數組存儲,數組的每一個元素都是一個Entry;而一個Entry就是一個單向鏈表,Entry鏈表中的每一個節點就保存了key-value鍵值對數據。
?
添加key-value鍵值對:首先,根據key值計算出哈希值,再計算出數組索引(即,該key-value在table中的索引)。然后,根據數組索引找到Entry(即,單向鏈表),再遍歷單向鏈表,將key和鏈表中的每一個節點的key進行對比。若key已經存在Entry鏈表中,則用該value值取代舊的value值;若key不存在Entry鏈表中,則新建一個key-value節點,并將該節點插入Entry鏈表的表頭位置。
刪除key-value鍵值對:刪除鍵值對,相比于“添加鍵值對”來說,簡單很多。首先,還是根據key計算出哈希值,再計算出數組索引(即,該key-value在table中的索引)。然后,根據索引找出Entry(即,單向鏈表)。若節點key-value存在與鏈表Entry中,則刪除鏈表中的節點即可。
HashMap和Hashtable的不同點
1 繼承和實現方式不同
HashMap 繼承于AbstractMap,實現了Map、Cloneable、java.io.Serializable接口。
Hashtable 繼承于Dictionary,實現了Map、Cloneable、java.io.Serializable接口。
2 線程安全不同
Hashtable的幾乎所有函數都是同步的,即它是線程安全的,支持多線程。
而HashMap的函數則是非同步的,它不是線程安全的。 若要在多線程中使用HashMap,需要我們額外的進行同步處理。 對HashMap的同步處理可以使用Collections類提供的synchronizedMap靜態方法,或者直接使用JDK 5.0之后提供的java.util.concurrent包里的ConcurrentHashMap類。
3 對null值的處理不同
HashMap的key、value都可以為null。
Hashtable的key、value都不可以為null。
Hashtable的key或value,都不能為null!否則,會拋出異常NullPointerException。
HashMap的key、value都可以為null。 當HashMap的key為null時,HashMap會將其固定的插入table[0]位置(即HashMap散列表的第一個位置);而且 table[0]處只會容納一個key為null的值,當有多個key為null的值插入的時候,table[0]會保留最后插入的value。
4 支持的遍歷種類不同
HashMap只支持Iterator(迭代器)遍歷。
而Hashtable支持Iterator(迭代器)和Enumeration(枚舉器)兩種方式遍歷。
5 通過Iterator迭代器遍歷時,遍歷的順序不同
HashMap是“從前向后”的遍歷數組;再對數組具體某一項對應的鏈表,從表頭開始進行遍歷。
Hashtable是“從后往前”的遍歷數組;再對數組具體某一項對應的鏈表,從表頭開始進行遍歷。
6 容量的初始值 和 增加方式都不一樣
HashMap默認的容量大小是16;增加容量時,每次將容量變為“原始容量x2”。
Hashtable默認的容量大小是11;增加容量時,每次將容量變為“原始容量x2 + 1”。
7 添加key-value時的hash值算法不同
HashMap添加元素時,是使用自定義的哈希算法。
Hashtable沒有自定義哈希算法,而直接采用的key的hashCode()。
?
HashMap和WeakHashMap的相同點
1 它們都是散列表,存儲的是“鍵值對”映射。
2 它們都繼承于AbstractMap,并且實現Map基礎。
3 它們的構造函數都一樣。
? ?它們都包括4個構造函數,而且函數的參數都一樣。
4 默認的容量大小是16,默認的加載因子是0.75。
5 它們的“鍵”和“值”都允許為null。
6 它們都是“非同步的”。
HashMap和WeakHashMap的不同點
1 HashMap實現了Cloneable和Serializable接口,而WeakHashMap沒有。
2 HashMap的“鍵”是“強引用(StrongReference)”,而WeakHashMap的鍵是“弱引用(WeakReference)”。
轉載于:https://www.cnblogs.com/wzyxidian/p/3783621.html
總結
以上是生活随笔為你收集整理的HashMap与HashTable联系与区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#中Dictionary的用法
- 下一篇: bzoj1715[Usaco2006 D