1. HashMap和HashTable的区别
(1) 使用
HashMap:key和value可以为null
HashTable:key和value不可以为null
(2) 底层数据结构:都是数组 + 链表
(3)源码
-
默认容量不同
HashTable:默认初始容量为11
HashMap:默认容量为16 -
Table的初始化时机
HashTable:构造函数中初始化,new对象时。
HashMap:初始为空数组,当添加第一个元素是数组容量变为16 -
是否支持fast-fail(快速失败机制)
HashTable:使用Enumeration进行遍历不支持快速失败机制,使用Iterator进行遍历时支持。
HashMap:使用Iterator进行遍历时支持 -
是否接受值为null的Key 或Value
HashTable:key和vlaue都不可以为空,否则会报空指针异常。
HashMap:key和value 都可以为空,源码中对hash和put都对null进行了处理。 -
根据hash值计算数组下标的算法
HashTable:Hash值的计算:
hashSeed ^ k.hashCode();
没有扰动处理,index重复率高。
(hash & 0x7FFFFFFF) % tab.length;
(hash & 0x7FFFFFFF)保证hash的值不为负数
HashMap:Hash值的计算:
int h = key.hashCode();
扰动处理:降低哈希冲突
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
h & (table.length-1)
- 扩容方式
HashTable:2倍+1 扩容
2倍+1 得到一个奇数,取余结果相比于偶数更分散
HashMap:2倍扩容
两者都会根据key重新计算所有元素的存储位置,算法相似,时间空间效率相同。
(4)数据遍历的方式
HashTable:HashTable可以使用Enumeration进行遍历,也可以使用Iterator进行遍历
HashMap:HashMap只可以使用Iterator进行遍历
(5)线程安全
HashTable:线程安全
加了synchronized关键字,所以是线程安全,但并不是绝对的线程安全。
HashMap:线程不安全
2. TreeMap与HashMap的区别
TreeMap与HashMap的相似之处:使用方法基本相同
区别:
(1)TreeMap元素大小有序。HashMap是无序的。
(2)TreeMap的存储位置是通过key的大小比较得出的,而HashMap是通过hash计算得到数组下标。
(3)TreeMap不允许插入null的key,因为null没办法比较大小。
(4)TreeMap实现了NavigableMap类,可以提供一系列的和大小相关的方法。
(5)TreeMap的时间复杂度:log(2N),HashMap的时间复杂度:O(1)
3. WeakHashMap与HashMap的区别
(1)WeakHashMap不能使用clone方法,不能进行序列化
implements Map<K,V>
WeakHashMap只实现了Map接口,没有实现clone接口和Serizaseable
(2)源码区别:对null 的处理情况不同
HashMap:当key为null时,返回对应的数组下标为0。
WeakHashMap:当key为null时,使用Object对象替换null,因此key实际存储的是new Object();但打印的时候还是null。
当key为非null时,两者的求取的hash方法是相同的:hashCode,扰动处理,&(table.length-1)
为什么用Obejct替换null?
因为WeakHashMap存储的都是弱引用,当key为null就会被GC回收掉。
(3)存储key的引用类型不同
集合只能存储引用类型的数据,不能存储普通类型
HashMap:存储的key是强引用类型。
WeakHashMap:存储的key是弱引用类型。
WeakHashMap对象存储的都是弱引用,key为“弱键”,当key为null时,GC时,存储的内容将就会被回收掉,如果key - vlaue中有强引用就不会被回收。