文章目录
一、HashMap vs Hashtable
一般而言,HashMap
几乎可以等价于Hashtable
,但在线程安全性、同步synchronized
、速度上存在差异。
1.1 区别
1.1.1 线程安全性不同
HashMap
是非synchronized
的,而Hashtable
是synchronized
,意味着Hashtable
是安全的。
1.1.2 key和value是否允许null值
HashMap
可以接受单个null
键(key
)值,可以有一个或多个键所对应的值为null
,但Hashtable
不接受;HashMap
允许将null
作为一个entry
的key
或者value
,而Hashtable
不允许。当get()
方法返回null
值时,可能是HashMap
中没有该键,也可能使该键所对应的值为null
。因此,在HashMap
中不能由get()
方法来判断HashMap
中是否存在某个键,而应该用containsKey()
方法来判断。
1.1.3 两个遍历方式的内部实现上不同
HashMap
的迭代器Iterator
是fail-fast
迭代器(相当于直接在容器中遍历,fail-safe
是创建了容器副本,遍历副本时修改不会引发异常),当在迭代过程中修改映射关系时,会造成并发修改异常ConcurrentModificationException
。而Hashtable
的enumerator
迭代器不是fail-fast
的。
1.1.4 是否提供contains方法
HashMap
把Hashtable
的contains()
方法去掉了,改成containsValue()
和containsKey()
,因为contains()
方法容易让人引起误解。Hashtable
则保留了contains()
,containsValue()
和containsKey()
三个方法,其中contains()
和containsValue()
功能相同。
1.1.5 hash值不同
- 哈希值的使用不同,
HashTable
直接使用对象的hashCode
。而HashMap
重新计算hash
值。
1.1.6 内部实现使用的数组初始化和扩容方式不同
Hashtable
和HashMap
它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable
中hash
数组默认大小是11,增加的方式是 old*2+1。HashMap
中hash
数组的默认大小是16,而且一定是2的指数。
1.1.7 继承的父类不同
Hashtable
继承自Dictionary
类,而HashMap
继承自AbstractMap
类。但二者都实现了Map
接口。
二、Hashtable vs ConcurrentHashMap
相比于HashMap
,Hashtable
与ConcurrentHashMap
是synchronized
的,上了锁,更加安全,但是仍有所区别。
2.1 区别
Hashtable
中采用的锁机制是一次锁住整个hash
表,从而同一时刻只能由一个线程对其进行操作。ConcurrentHashMap
中则是一次锁住一个桶。ConcurrentHashMap
默认将hash
表分为16个段,诸如get
,put
,remove
等常用操作只锁当前需要用到的桶。
三、HashMap vs LinkedHashMap
3.1 区别
Linkedhashmap
是hashmap
子类多了after
和behind
方法。LinkedHashMap
比HashMap
多维护了一个链表。