java.util.Hashtable
1. 内部由内部类Entry存储单节点数据,单向链表(hash冲突时往后放)。table为Entry数组,hash后决定Entry存在table[?]
private static class Entry<K,V> implements Map.Entry<K,V> {
Entry<K,V> next;
2. Hashtable初始默认容量11,可容纳11 * 0.75个节点
public Hashtable() {
this(11, 0.75f);
}
3. get() put()都是synchronized的,区别HashMap
4. put()的key与value都不能是null
5. index为hash值, 然后判断table[index],为空直接填入,否则遍历,如果找到key相同就更新值返回原值,或遍历至表尾添加
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;//tab为table数组,tab.length为Hashtable的容量
6. rehash与扩容, rehash()发生, 当Hashtable存的数量大于容量*负载因子(默认11 * 0.75),发生扩容,为原容量2倍+1,原数据重新hash放入扩容后的table里【移动的是引用】【开销在new 新容量的table】
int newCapacity = (oldCapacity << 1) + 1; //扩容
Entry<?,?>[] newMap = new Entry<?,?>[newCapacity]; //创建新table
int index = (e.hash & 0x7FFFFFFF) % newCapacity; //重新散列rehash
7. 较之HashMap,【Hashtable是线程安全的】初始容量不像HashMap(初始容量必须为2的次方),最好【初始化一个合适大小的Hashtable】,防止扩容开销