Map與HashMap,Hashtable,HashSet的區別
前言:
自開始接手這JAVA寫的框架以來,遇到各種問題,發現與PYTHON,習慣真不一樣,在處理YAML資料時,用到hashmap,map等,各種糾結,幸虧得到,小林同學的幫忙,終於問題解決了,因此參考網路內容,順便總結下,這各種鬼的用法,當然,還是建議各位用PYTHON,PYTHON把各種型別轉換過程全給你做了
生命太短,你應該用PYTHON。HashTable和HashMap區別
區別一:繼承的父類不同
Hashtable繼承自Dictionary類,而HashMap繼承自AbstractMap類。但二者都實現了Map介面。
public class Hashtable<K ,V> extends Dictionary<K,V>
implements Map<K,V>, Cloneable, Serializable
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
- 1
- 2
- 3
- 4
- 5
區別二:執行緒安全性不同
Hashtable 中的方法是Synchronize的,而HashMap中的方法在預設情況下是非Synchronize的。
區別三:是否提供contains方法
HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey,因為contains方法容易讓人引起誤解。
Hashtable則保留了contains,containsValue和containsKey三個方法,其中contains和containsValue功能相同。
**區別四:**key和value是否允許null值
其中key和value都是物件,並且不能包含重複key,但可以包含重複的value。
Hashtable中,key和value都不允許出現null值。
HashMap中,null可以作為鍵,這樣的鍵只有一個;可以有一個或多個鍵所對應的值為null。當get()方法返回null值時,可能是 HashMap中沒有該鍵,也可能使該鍵所對應的值為null。因此,在HashMap中不能由get()方法來判斷HashMap中是否存在某個鍵, 而應該用containsKey()方法來判斷。
PS:這個面試喜歡問。
區別五:雜湊值的計算方法不同,Hashtable直接使用的是物件的hashCode,而HashMap則是在物件的hashCode的基礎上還進行了一些變化。
//Hashtable中可以看出的是直接採用關鍵字的hashcode作為雜湊值
int hash = key.hashCode();
//然後進行模運算,求出所在譁然表的位置
int index = (hash & 0x7FFFFFFF) % tab.length;
//HashMap中的實現
//這兩行程式碼的意思是先計算hashcode,然後再求其在雜湊表的相應位置
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
//求位於雜湊表中的位置
static int indexFor(int h, int length) {
return h & (length-1);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
區別六:內部實現使用的陣列初始化和擴容方式不同,記憶體初始大小不同,HashTable初始大小是11,而HashMap初始大小是16
public Hashtable() {
//從這裡可以看出,預設的初始化大小11,
//這裡的11並不是11個位元組,而是11個 Entry,這個Entry是
//實現連結串列的關鍵結構
//這裡的0.75代表的是裝載因子
this(11, 0.75f);
}
public HashMap() {
//這個預設的裝載因子也是0.75
this.loadFactor = DEFAULT_LOAD_FACTOR;
//預設的痤為0.75*16
threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
//這裡開始是預設的初始化大小,這裡大小是16
table = new Entry[DEFAULT_INITIAL_CAPACITY];
init();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
Hashtable採用的是2*old+1,而HashMap是2*old
HashMap和HashSet的區別
HashSet實質
(1)HashSet是set的一個實現類,hashMap是Map的一個實現類,同時hashMap是hashTable的替代品(為什麼後面會講到).
(2)HashSet以物件作為元素,而HashMap以(key-value)的一組物件作為元素,且HashSet拒絕接受重複的物件.HashMap可以看作三個檢視:key的Set,value的Collection,Entry的Set。 這裡HashSet就是其實就是HashMap的一個檢視。
HashSet內部就是使用Hashmap實現的,和Hashmap不同的是它不需要Key和Value兩個值。
往hashset中插入物件其實只不過是內部做了
public boolean add(Object o) {
return map.put(o, PRESENT)==null;
}