// 初始化,默认初始化大小为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接口。