implements Map<K,V>, Cloneable, Serializable {}
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable {
public synchronized Enumeration<K> keys() {
return this.<K>getEnumeration(KEYS);
}
public synchronized Enumeration<V> elements() {
return this.<V>getEnumeration(VALUES);
}
}
|
Hashtable
|
HashMap
|
併發操作
|
使用同步機制,
實際應用程序中,僅僅是Hashtable本身的同步並不能保證程序在併發操作下的正確性,需要高層次的併發保護。
下面的代碼試圖在key所對應的value值等於x的情況下修改value爲x+1
{
value = hashTable.get(key);
if(value.intValue()== x){
hashTable.put(key, new Integer(value.intValue()+1));
}
}
如2個線程同時執行以上代碼,可能放入不是x+1,而是x+2.
|
沒有同步機制,需要使用者自己進行併發訪問控制
|
數據遍歷的方式
|
Iterator 和 Enumeration
|
Iterator
|
是否支持fast-fail
|
用Iterator遍歷,支持fast-fail
用Enumeration不支持fast-fail.
|
支持fast-fail
|
是否接受值爲null的Key 或Value?
|
不接受
|
接受
|
根據hash值計算數組下標的算法
|
當數組長度較小,並且Key的hash值低位數值分散不均勻時,不同的hash值計算得到相同下標值的機率較高
hash = key.hashCode();
index=(hash&0x7FFFFFFF) % tab.length;
|
優於hashtable,通過對Key的hash做移位運算和位的與運算,使其能更廣泛地分散到數組的不同位置
hash = hash (k);
index = 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);
}
|
Entry數組的長度
|
Ø 缺省初始長度爲11,
Ø 初始化時可以指定initial
capacity
|
Ø 缺省初始長度爲16,
Ø 長度始終保持2的n次方
Ø 初始化時可以指定initial
capacity,若不是2的次方,HashMap將選取第一個大於initial capacity 的2n次方值作爲其初始長度
|
LoadFactor負荷因子
|
0.75
|
|
負荷超過(loadFactor * 數組長度)時,內部數據的調整方式
|
擴展數組:2*原數組長度+1
|
擴展數組: 原數組長度 * 2
|
兩者都會重新根據Key的hash值計算其在數組中的新位置,重新放置。算法相似,時間、空間效率相同
|