HashTable也是一个散列表,它存储的内容是键值对映射。HashTable继承于Dictionary,实现了Map、Cloneable、java.io.Serializable接口。HashTable的函数都是同步的,这意味着它是线程安全的。它的Key、Value都不可以为null。此外,HashTable中的映射不是有序的。
//为一个Entry[]数组类型,Entry代表了“拉链”的节点,每一个Entry代表了一个键值对,哈希表的"key-value键值对"都是存储在Entry数组中的。
private transient Entry<?,?>[] table;
//HashTable的大小,注意这个大小并不是HashTable的容器大小,而是他所包含Entry键值对的数量。
private transient int count;
//Hashtable的阈值,用于判断是否需要调整Hashtable的容量。threshold的值=“容量*加载因子”
private int threshold;
//加载因子。
private float loadFactor;
//用来实现“fail-fast”机制的(也就是快速失败)。所谓快速失败就是在并发集合中,其进行迭代操作时,若有其他线程对其进行结构性的修改,这时迭代器会立马感知到,并且立即抛出ConcurrentModificationException异常,而不是等到迭代完成之后才告诉你(你已经出错了)
private transient int modCount = 0;
//获取synchronized锁
public synchronized V put(K key, V value) {
// Make sure the value is not null
//如果value是空抛出异常
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry<?,?> tab[] = table;
//计算key的哈希值和index
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> entry = (Entry<K,V>)tab[index];
//遍历对应位置列表
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 = hash(key);//先根据key计算hash值
int index = (hash & 0x7FFFFFFF) % tab.length;//再根据hash值找到索引
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {//遍历entry链
if ((e.hash == hash) && e.key.equals(key)) {//若找到该键
return e.value;//返回对应的值
}
}
return null;//否则返回null
}
public synchronized V remove(Object key) {
Entry<?,?> tab[] = table;
//计算key的哈希值和index
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for(Entry<K,V> prev = null ; e != null ; prev = e, e = e.next) {
//遍历对应位置的链表,寻找待删除节点
if ((e.hash == hash) && e.key.equals(key)) {
modCount++;
//更新前驱节点的next,指向e的next
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
V oldValue = e.value;
e.value = null;
//返回待删除节点的value值
return oldValue;
}
}
//如果不存在,返回null
return null;
}
和hashmap的主要区别:
原文:https://www.cnblogs.com/jiezao/p/13461597.html