【HashMap,HashTable,ConcurrentHashMap的共同点和区别】

1.三者简述

  HashMap是Map的衍生,也是map接口的实现类,底层为:数组+链表实现(1.8加入了红黑树),以键值对的形式存储,根据hash函数来实现映射关系,HashMap用Key的哈希值来存储和查找键值对。当插入一个value时,HashMap会计算Key的哈希值然后把value和这个哈希值相关联。

他的key和value可以为null;

它根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。 HashMap最多只允许一条记录的键为null,允许多条记录的值为null。HashMap非线程安全,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用 Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap。

 

  HashTable:底层:数组+链表实现,继承自Dictionary类,并且和Hashmap一样,都是map的实现类,很多映射的常用功能与HashMap类似,但是它是线程安全的,任一时间只有一个线程能写Hashtable,而且其key和value不能为null;并发性不如ConcurrentHashMap,因为ConcurrentHashMap引入了分段锁。Hashtable不建议在新代码中使用,不需要线程安全的场合可以用HashMap替换,需要线程安全的场合可以用ConcurrentHashMap替换。

 

  ConcurrentHashMap:底层为数组+链表+红黑树(1.8),ConcurrentHashMap的key和Value都不能为null,继承自抽象类AbstractMap,而AbstractMap则是Map接口的实现类,它是线程安全的。和HashMap功能基本一致,主要是为了解决HashMap线程不安全问题。

 

2.大致区别

  

  key-value 线程安全

默认大小(初始size)和扩容

extends/implement  底层实现    
HashMap 均可为null 线程不安全

初始size=16,

扩容:newsize = oldsize*2

是Map接口的实现类 1.8中是数组+链表+红黑树    
HashTable 均不可为null 线程安全

初始size为11,

扩容:newsize = olesize*2+1

继承自Dictionary类,

也是Map接口的实现类

数组+链表    
ConcurrentHashMap 均不可为null 线程安全

初始size为16,

扩容:当数组存储的元素的数量大于阈值就会进行扩容;

阈值也就是0.75*数组长度,也就是段内元素超过该段

对应Entry数组长度的75%触发扩容,不会对整个Map进行扩容

继承自抽象类AbstractMap,
而AbstractMap则是Map接口
的实现类
底层为数组+链表+红黑树(1.8)    

 

3.关于线程安全

 可以参考这篇https://www.jianshu.com/p/19864e6c126f

 

 

参考:https://blog.csdn.net/heting717/article/details/103868691

  https://www.cnblogs.com/heyonggang/p/9112731.html

  并感谢小猴同学的指点@_@

【HashMap,HashTable,ConcurrentHashMap的共同点和区别】

原文地址:https://www.cnblogs.com/dabuliu/p/14472163.html