HashMap 和 HashTable 的区别

353 阅读1分钟

1.容器整体结构:

HashMapkeyvalue允许为null,HashMap遇到key为null的时候,调用putForNullKey方法进行处理,而对value没有处理。

Hashtablekeyvalue不允许为 null。Hashtable遇到null,直接返回NullPointerException

2.容量设定与扩容机制:

HashMap默认初始化容量为16,并且容器容量一定是 2的n次方,扩容时,是以原容量2倍的方式进行扩容。

Hashtable默认初始化容量为11,扩容时,是以原容量2倍再加1的方式进行扩容。
int newCapacity = (oldCapacity << 1) + 1;

3.散列分布方式(计算存储位置):

HashMap是先将key键的hashCode经过扰动函数扰动后得到hash值,然后再利用**hash & (length - 1)**的方式代替取模,得到元素的存储位置。

Hashtable则是除留余数法进行计算存储位置的(因为其默认容量也不是 2 的 n 次方。所以也无法用位运算替代模运算),int index = (hash & 0x7FFFFFFF) % tab.length;

由于HashMap的容器容量一定是2的n次方,所以能使用hash & (length - 1)的方式代替取模的方式计算元素的位置提高运算效率,但Hashtable的容器容量不一定是2的n次方,所以不能使用此运算方式代替。

4.线程安全(最重要):

HashMap不是线程安全,如果想线程安全,可以通过调用synchronizedMap(Map<K,V> m)使其线程安全。但是使用时的运行效率会下降,所以建议使用ConcurrentHashMap容器以此达到线程安全。

Hashtable则是线程安全的,每个操作方法前都有synchronized修饰使其同步,但运行效率也不高,所以还是建议使用ConcurrentHashMap容器以此达到线程安全。

因此,Hashtable是一个遗留容器,如果我们不需要线程同步,则建议使用HashMap,如果需要线程同步,则建议使用 ConcurrentHashMap