HashTable 散列表,基于哈希表实现的,存储内容是(key,value)映射。
继承于Dictionary,实现Map,Cloneable、java.io.Serializable接口,支持序列化,可克隆。而Map是<key,value>键值对的接口。
//Hashtable的源码
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable
HashTable函数都是同步的,是线程安全的,它的key,value都不能为null。
table是一个Entry[]数组类型,而Entry是一个单向链表,用来存储键值对。
存储方法
public synchronized V put(K key, V value) {
// 确保value不为null
if (value == null) {
throw new NullPointerException();
}
/*
* 确保key在table[]是不重复的
* 处理过程:
* 1、计算key的hash值,确认在table[]中的索引位置
* 2、迭代index索引位置,如果该位置处的链表中存在一个一样的key,则替换其value,返回旧值
*/
Entry tab[] = table;
int hash = hash(key); //计算key的hash值
int index = (hash & 0x7FFFFFFF) % tab.length; //确认该key的索引位置
//迭代,寻找该key,替换
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
V old = e.value;
e.value = value;
return old;
}
}
modCount++;
if (count >= threshold) { //如果容器中的元素数量已经达到阀值,则进行扩容操作
rehash();
tab = table;
hash = hash(key);
index = (hash & 0x7FFFFFFF) % tab.length;
}
// 在索引位置处插入一个新的节点
Entry<K,V> e = tab[index];
tab[index] = new Entry<>(hash, key, value, e);
//容器中元素+1
count++;
return null;
}
get()方法
public synchronized V get(Object key) {
Entry tab[] = table;
int hash = hash(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
return e.value;
}
}
return null;
}
HashTable 和 HashMap的不同 转载自【http://blog.csdn.net/jinhuoxingkong/article/details/52022999】
Hashtable和HashMap到底有哪些不同呢?
- 基类不同:HashTable基于Dictionary类,而HashMap是基于AbstractMap。Dictionary是什么?它是任何可将键映射到相应值的类的抽象父类,而AbstractMap是基于Map接口的骨干实现,它以最大限度地减少实现此接口所需的工作。
public class Hashtable extends Dictionary implements Map public class HashMap extends AbstractMap implements Map
- null不同:HashMap可以允许存在一个为null的key和任意个为null的value,但是HashTable中的key和value都不允许为null。
- 线程安全:synchronized与否。HashMap时单线程时才安全的,单线程是HashMap的速度也更快;Hashtable是多线程安全的,所 以多线程可以共享一个hashTable。
- 遍历方式不同:HashMap仅支持Iterator的遍历方式,Hashtable支持Iterator和Enumeration两种遍历方式。Enumeration可以枚举对 象集合的元素。这个传统接口已经被Interator取代。
- 哈希值使用不同,HashTable直接使用对象key的hashCode作为hash值。而HashMap是对hashCode又进行hash算法计算得到hash值。
- 内部实现使用的数组初始化和扩容方式不同,初始化默认容量11/16,HashTable没有要求数组大小为2^n。扩容时HashTable*2+1;HashMap*2。
- HashTable有contains()方法,HashMap没有。HashMap不能用get()方法判断是否存在某个键,要用Map.containsKey( )方法。因为HashMap中允许键值为null,如果get(Object key1)是null,可能有两种情况,1.没有key1这个键,2.key1键值对应的value是null.键值对<"04",null>
因为hashTable是同步的,所以任何线程要更改HashTable都有先获得同步锁,其他线程等待锁释放后,才能再次获取同步锁来更新HashTable。
Map m = Collections.synchronizeMap(hashMap);//让HashMap做到同步