HashMap 与 Hashtable的区别

HashMap和HashTable都实现了Serializable接口,因此它支持序列化,实现了Cloneable接口,能被克隆,实现Map接口。

HashMap的父类AbstractMap类。
Hashtable的父类Dictionary。

Hashtable既不支持Null key也不支持Null value。都会抛空指针。
HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。

Hashtable是线程安全的,它的每个方法中都加入了Synchronize方法。
HashMap不是线程安全的。

Hashtable默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。
HashMap默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。

计算hash值的方法不同,Hashtable直接使用对象的hashCode。
计算hash值的方法不同,HashMap使用 扰动函数。先获取对象的hashCode,然后在将hashCode右移16位(高位到低位),然后将2次的值异或求值得出一个新的hash值  

(h = key.hashCode()) ^ (h >>> 16)

HashMap 与 concurrentHashMap

hashMap线程不安全,concurrentHashMap线程是安全的,hashTable线程安全的
HashMap的线程不安全主要体现在下面两个方面:
   1.在JDK1.7中 数组 + 链表,当并发执行扩容操作时会造成环形链和数据丢失的情况。
   2.在JDK1.8中 数组 + 链表\红黑树,在并发执行put操作时会发生数据覆盖的情况。

1.8中当 链表长度>8 && table数组长度>=64 的时候会自动转换成红黑树 

条件⼀:每个节点要么是红⾊,要么是⿊⾊。
条件⼆:根节点⼀定是⿊⾊的。
条件三:每个叶⼦节点⼀定是⿊⾊。
条件四:如果⼀个节点是红⾊,那么它的左右⼦节点⼀定都是⿊⾊的。
条件五:从任意⼀个节点到叶⼦节点,所经过的⿊⾊节点的数量⼀样多。
左旋:自己变为右孩子的左孩子,如果右孩子存在左孩子的话,将其变成自己的右孩子
右旋:自己变为左孩子的右孩子,如果左孩子存在右孩子的话,将其变成自己的左孩子

当插入数据时 table数组中某一个链表长度>8时 会执行 treeifybin的方法,方法中会先判断整个数组长度如果长度<64 就只执行扩容数据迁移的工作。 当数组长度>=64 执行转换红黑树的操作。

为什么HashMap的长度是2的n次幂

这样(数组长度-1)正好相当于一个“低位掩码”。“与”操作的结果就是散列值的高位全部归零,只保留低位值,用来做数组下标访问。 i = (n - 1) & hash

​​​​​​​

1.在JDK1.7中,当并发执行扩容操作时会造成环形链和数据丢失的情况。

2.在JDK1.8中,在并发执行put操作时会发生数据覆盖的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值