集合框架库Map总结(HashMap、HashTable、TreeMap、WeakHashMap的区别)

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
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中有强引用就不会被回收。

你可能感兴趣的:(JavaSE)