构造器
无参构造
public Hashtable() {
this(11, 0.75f);
}
成员变量
// 底层数组
private transient Entry<K,V>[] table;
//键值对总数
private transient int count;
//将要成功添加key-value时进行判断 ,若count >= threshold (table表已有的键值对总数 >= 阈值) 则进行扩容
private int threshold;
//负载因子
private float loadFactor;
//hashtable被改变的次数,用于快速失败机制
private transient int modCount = 0;
put方法
// HashTable put方法
public synchronized V put(K key, V value) {
// value 为 null ,则抛异常
if (value == null) {
throw new NullPointerException();
}
// table 赋给一个 临时 Entry数组
Entry<?,?> tab[] = table;
// 获取 key的 hashCode 当成 hash ,key为null则抛异常
int hash = key.hashCode();
// hash 经过运算 得到 在 table表的索引
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
// 遍历该索引处的链表,判断key是否相同
Entry<K,V> entry = (Entry<K,V>)tab[index];
for(; entry != null ; entry = entry.next) {
// 如果 key相等 则替换 value ,并返回 就 value
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
entry.value = value;
return old;
}
}
// 如果该条链表都和 key 不同 ,则创建一个 Entry,存放 key-value ,并返回一个 null
addEntry(hash, key, value, index);
return null;
}
addEntry方法及Entry构造器
private void addEntry(int hash, K key, V value, int index) {
modCount++;
Entry<?,?> tab[] = table;
// count 相当于 size threshold则是阈值 ,count >= 阈值 则扩容 这是在添加元素之前判断
if (count >= threshold) {
// Hashtable每次扩容,容量都为原来的2倍加1,而HashMap为原来的2倍.
rehash();
// 扩容完成之后 重新运算得到新的 table表索引下标
tab = table;
hash = key.hashCode();
index = (hash & 0x7FFFFFFF) % tab.length;
}
// Creates the new entry.
@SuppressWarnings("unchecked")
// 不扩容就用原来的下标 , 扩容就用新运算得到的下标 ,再进行添加
Entry<K,V> e = (Entry<K,V>) tab[index];
// 将 新Entry对象 添加到 链表得首节点
tab[index] = new Entry<>(hash, key, value, e);
count++;
}
protected Entry(int hash, K key, V value, Entry<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}