// 初始化,默認初始化大小爲11,區別於HashMap的默認初始化大小16
public Hashtable() {
this(11, 0.75f);
}
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry<?,?> tab[] = table;
// 直接使用對象的hashCode進行計算對象的數組索引
int hash = key.hashCode();
// 保留對象hash值的低7*8+3=59位,對tab數組的長度進行取模,來獲取對應的位置索引
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> entry = (Entry<K,V>)tab[index];
// 如果已經存在,就添加到鏈表的next
for(; entry != null ; entry = entry.next) {
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
entry.value = value;
return old;
}
}
// 否則直接進行添加
addEntry(hash, key, value, index);
return null;
}
public synchronized V get(Object key) {
Entry<?,?> tab[] = table;
int hash = key.hashCode();
// 首先計算位置索引,方法和put時的算法保持一致
int index = (hash & 0x7FFFFFFF) % tab.length;
// 從該位置獲取到Entry對象,並遍歷整個鏈表,判斷是否存在和參數key相同的key,有則返回其value
for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
return (V)e.value;
}
}
// 否則返回null
return null;
}
// 返回Hashtable的迭代器,其實和HashMap的iterator相同。HashMap中的iterator只是在Collection集合框架中對迭代器進行了統一
public synchronized Enumeration<V> elements() {
return this.<V>getEnumeration(VALUES);
}
// Hashtable 的迭代器遍歷示例
Hashtable<String,String> ht = new Hashtable<String,String>();
ht.put("1", "1") ;
ht.put("2", "2") ;
Enumeration<String> elements = ht.elements() ;
while (elements.hasMoreElements()){
String str = elements.nextElement() ;
System.out.println(str);
}
特性:
1.Hashtable 爲線程安全,實現的方式爲在對應的方法上全部添加同步關鍵字synchronized
2.關聯特性1,使用synchronized降低了處理速度,效率低於HashMap
3.初始化大小爲11,擴展爲2*old+1,HashMap的初始化大小爲16,並且擴展也必須是2的冪次方
4.計算位置索引時,使用的是對象的hash值直接進行計算,但最後的取模運算需要用到除法,除法比較耗時。HashMap地層數組長度保證爲2的冪次方,這樣計算位置索引值時不需要做除法運算,有助於提升效率。但會增加數據碰撞的機率,爲了減少碰撞機率,HashMap在獲取hash後,會對hash做一些簡單的運算,有助於打散數據,減少碰撞,並同時不至於抵消不做除法所帶來的效率提高。
5.Hashtable 繼承於Dictionary字典類,該類已過時,Hashtable也已過時。HashMap繼承於AbstractMap。但兩者均實現了Map接口。