HashMap
-
HashMap是线程不安全的,可以存储null键和null值。在JDK1.7是由数组+链表实现的,
到JDK1.8引入了红黑树(当链表长度超过8时,将链表结构转换成红黑树结构,利用红黑树的快速增删改查提高性能)
。 - HashMap的数组初始默认长度(tablelength)为16,加载因子(loadfactor)为0.75。当Map中的元素数量超过当前tablelength*loadfactor时,HashMap的table会自动扩容,新的数组长度是原来的两倍。table的长度一直保持2的次幂,配合hashcode计算方法和最后的index=h&(length-1)方法可以使元素的散列程度更好。
- HashMap每次扩容后原先的元素都会重新计算索引位置,重新插入。扩容的操作浪费时间和资源,因此在使用HashMap时应该预先给定一个适合的table容量。
- 加载因子太大,会造成查找效率降低;加载因子太小,会造成空间浪费。
- ConcurrentHashMap改善了HahMap的线程安全性。
HashTable
- HashTable是线程安全的,不可以存储null值和null键。底层也是数组+链表的形式实现。由于线程的安全性,它的效率会降低。
- 初始容量是11,扩容时,newsize=oldsize*2+1;
两者的区别
- Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类。但二者都实现了Map接口。
- Hashtable 中的方法是Synchronize的,而HashMap中的方法在缺省情况下是非Synchronize的。
- key和value是否允许null值
- hash值不同:HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
- 内部实现使用的数组初始化和扩容方式不同。
版权声明:本文为LEverything原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。