HashMap、Hashtable区别
2018-08-29 本文已影响27人
BlackJava
前几篇文章,我们分别探究了HashMap,Hashtable,这篇文章我们来分析一下 他们之间的区别
Collections.synchronizedMap(),生成的 SynchronizedMap的区别,查看源码我们可以发现 SynchronizedMap 只是对对应Map实现的一个封装,只是添加了对象锁,但是不像Hashtable 锁住当前的对象,SynchronizedMap 锁住的是当前的包装类访问限制,内部的Map 类开放的,也就是说如果获取到对应的 Iterator,可以再对其进行put, remove 操作。
第一:线程安全性(大家熟知的)
HashMap → 线程不安全
Hashtable → 线程安全,使用 synchronized 修饰方法,锁住对象,达到线程安全
SynchronizedMap → 严格线程安全,所有的方法都添加了synchronized 对象锁
第二:Null数据存储不同
HashMap → 可以存储null数据(key,value 都可以为null)而且key == null 数据只能存放一条
Hashtable → 严格控制,不能存储null数据(key,value 都不可以为 null)
第三:使用的存储结构不同
HashMap → 数组 + 链表 + 红黑树
Hashtable → 数组 + 链表
第四:使用的散列算法不同(碰撞率我们下次来分析)
HashMap → 采用hashCode 向右移位 16位,然后 异或运算,再 对数组长度 - 1 做 & 位运算
hash = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
index = hash & (tab.length - 1)
Hashtable → 采用 对数组长度 做 % 运算
hash = key.hashCode()
int index = (hash & 0x7FFFFFFF) % tab.length
第五:使用的扩容算法不同
HashMap → 数组长度,容量都是原来的 2 倍
newCapacity = oldCapacity << 1
newThreshold = oldThreshold << 1
Hashtable → 数组长度是原来的 2倍 + 1,容量是 新的数组长度 * 0.75
newCapacity = (oldCapacity << 1) + 1
threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1)
第六:链表插入数据的位置不同
HashMap → 链表的结尾插入数据
Hashtable → 链表的开始插入数据