一、HashMap与HashTable的区别
1.来历
HashTable是一种键值映射的数据结构,自从java发布就存在,而HashMap是jdk1.2后才出现的,虽然说HashTable出现得早且线程安全,但是效率很低已经弃用了,现在HashMap逐渐成为主流
2.底层数据结构不同
HashTable底层使用的是数组➕链表,而HashMap底层则是数组➕链表+红黑树
3.线程安全性不同
HashTable是线程安全的,这是因为在每个方法中加入了Synchronize用来实现线程同步,在多线程并发的情况下直接用HashTable就可以实现线程安全,HashMap则是线程不安全的。
但是使用HashTable效率太低了,这是因为当线程访问HashTable的同步方法时,其他线程只有堵塞等待占用线程执行完
而HashMap在多线程环境中使用put方法导致形成环形链表从而形成死循环,导致线程不安全
这个时候ConcurrentHashMap使用分段锁,对不同的数据段使用不同的锁,可以支持多个线程同时访问不同数据段,这样既保证了线程安全性也提高了并发效率
4.key和value是否允许null值
HashTable中key和value都不允许为null,而HashMap可以且只允许一个key值为null,而value允许一个或者多个为null
5.数据初始化与扩容机制不同
HashTable默认容量为11,而HashMap默认容量为16,HashTable扩容时会将容量变为原来的2被加1,而HashMap会将容量变为2倍。HashTable之所以扩容时会将容量变为2倍加1是因为:HashTable采用取模方式计算数组下标,同时尽量为素数或者奇数,目标是减少Hash碰撞让计算出来的下标更加分散,让元素均匀分布于数组中的多个位置
二、为啥HashMap要用数组➕链表➕红黑树
1.数组:使用数组可以利用key的hash值能够快速查询元素
2.链表:由于两个对象调用哈希函数计算哈希码值一致导致计算数组的索引值相同,这就是hash冲突。通过将索引值相同的元素放在一个链表中去解决hash冲突
3.红黑树:如果超过8个节点的链表就使用红黑树来代替链表,从而实现查询性能的提升