引子
看到一个关于HashMap和HashTable对比的面试题,于是简单看了下HashTable的源码,简单记录下。
概述
与HashMap相似的哈希表结构,有很多不同点:
- 节点数组的初始化是在构造函数中完成的,初始容量11,负载因子0.75;
- hashTable内部使用synchronized实现线程安全;
- hashTable的k v 都不能为null,否则NPE;
- 内部使用数组 + 链表的结构,没有链表转红黑树的过程。
- 添加元素时检测并触发扩容,扩容时,容量是原容量的2倍+1
注意:仅做源码学习,不推荐使用。
" 如果不需要线程安全的实现,建议使用HashMap代替Hashtable 。如果需要线程安全的高并发实现,则建议使用java. util. concurrent. ConcurrentHashMap代替Hashtable "
------------来自hashTable类说明
put流程
private void addEntry(int hash, K key, V value, int index) {
Entry<?,?> tab[] = table;
if (count >= threshold) { // 触发扩容
// Rehash the table if the threshold is exceeded
rehash(); // 2倍 +1 扩容,复制数组,重新计算元素的hash
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];
tab[index] = new Entry<>(hash, key, value, e);
count++;
modCount++;
}
题外话:
与HashMap和ConcurrentHashMap不同的是,hashTable中,
put
和 **putIfAbsent
**方法是两个独立的方法,竟然没有通过参数传递来复用。重复代码,妥妥的!!!在HashMap和ConcurrentHashMap中,这种情况就没有了😄。