相同

  • 都是 KV 集合
  • 都实现了 Map 接口
  • 都基于哈希表实现 O(1) 时间复杂度的查找插入和删除
  • 都不保证映射中元素的迭代顺序(LinkedHashMap可以维护)

不同

  • 线程安全:HashMap 不安全,另外两个安全
  • 同步机制
    • HashMap无
    • HashTable 使用 synchronized 修饰大部分公共方法
    • ConcurrentHashMap 使用 CAS 锁 + Node 锁的细粒度锁
  • 性能上:
    • HashMap 单线程最快
    • HashTable 最慢
    • ConcurrentHashMap 并发下优秀
  • null key:
    • HashMap允许(最多一个)
    • HashTable 不允许
    • ConcurrentHashMap 不允许
  • null value
    • HashMap 允许
    • HashTable不允许
    • ConcurrentHashMap 不允许
  • 迭代器
    • HashMap:快速失败,并发导致不同步时抛出异常 ConcurrentModificationException
    • HashTable:没有快速失败
    • ConcurrentHashMap:弱一致性,不抛 ConcurrentModificationException,遍历时可能反映部分修改

对 Null key/value 的处理

  • HashMap:可以有一个 null key 多个 null value,null key进行特殊处理,在比较 key 时会用 key == null 而不是 key.hashcode()

为什么 HashTable 和 ConcurrentHashMap 不支持 Null

  • 避免二义性:为了防止 containsKey(key) 和 get(key) 之间的并发修改导致的数据不可靠,线程安全的 Map 严格限制 get(key) null 的含义为 key 不存在这个 Map 中(这个设计禁止 null value)
  • 健壮性:HashMap 使用了特殊处理的方式对待 null,HashTable 和 ConcurrentHashMap 会认为这不够健壮