基础之HashMap理解

一。JDK1.8以后改动

HashMap使用链表法避免哈希冲突(相同的hash值),当链表长度大于TREEIFY_THRESHOLD(默认为8)时,将链表转为红黑树,当小于UNTREEIFY_THRESHOLD(默认为6)时,又会转回链表以达到性能均衡。

 

二。什么时候扩容

进行PUT操作时,判断当前容器元素个数达到阈值(当前数组长度乘加载因子的值 )就自动扩容

扩容是重新计算容量,根据计算出容量定义一个新的容器,将原窗口元素放到新容器里。

 

三。HashMap为什么是线程不安全的

1.put的时候导致的多线程数据不一致。

比如有线程A和B,首先A要插入一个键值到HashMap中,首先要计算记录要插入的hash桶的索引坐标,然后取到该桶的链表头结点,此时线程A时间片用完。然后B开始执行,假设A计算出来的hash桶索引和B要插入计算出来的hash桶索引一关的话,那么B成功插入之后,A再次被调度执行时,它依然有过期的链表头,而且是不知道是过期的。这样就覆盖了线程B插入的记录,B插入的数据就会消失,这样就数据不一致了

2.resize而引起的死循环

当HashMap自动扩容时,当有2个线程同时检测到元素个灵长超过阀值(数组大小*负载因子),这时两个线程都会在put中调用resize();两个线程同时修改一个链表结构会产生一个循环链表,接下来再通过 GET()获取某一个元素就会出现死循环。

 

四。HashMap和HashTable的区别

双方都实现了Map接口,主要区别有:线程安全,同步,以及速度

1.HashMap是非synchronized的,并可以接受null(可以接受为null的链值),而HashTable则不允许null的键值。

2.HashTable是synchronized,意味着HashTable是线程安全的,多个线程可以共享一个HashTable;如果没有正确的同步,多个线程是不能共享HashMap的。ps:java5有一个ConcurrentHashMap.它可以替代HashTable,且扩展性更好

3.由于HashTable是线程安全的也是synchronized,所以在单线程下它比HashMap要慢,如果不需要同步且单线程那么使用HashMap性能要更好。

4.HashMap不能保证随着时间的推移MAP中的元素次序是不变的。

5.迭代器不同,HashMap的迭代器(Iterator)是fail-fast迭代器,而HashTable的enumerator迭代器不是fail-fast的。

 

五。术语介绍

1.sychronized意味着一次只能有一个线程能够更改HashTable。任何其它线程要更新时要先获取同步锁,其它线程要等 同步锁被释放才能再次获取同步锁更新HashTable.

 

六。HashMap可以通过下面语句进行同步

Map m = Collections.synchronizeMap(hashMap);

 

七。JDK1.7和JDK1.8里面HashMap的不同点

1.1.7中用的是头插法,1.8及之后用的是尾插法,原因:1.7是单链表进行的纵向延伸,头插法能提高插入效率,但是也会容易出现逆序环形链表死循环问题,1.8之后加入了红黑树使用尾插法,避免出现逆序环形链表死循环问题

2.扩容后数据存储位置的计算方式不一样

1)在1.7中直接用hash值和需要扩容的二进制数进行&(这就是为什么扩容的时候为啥一定是2的多少次幂的原因,因为2的N次幂的情况下最后一位二进制数才一定是1,能最大程序减少碰撞)

2)在1.8中,直接用的扩容 前的原始位置——扩容的大小值,而不是1.7的那种异域的方法,这种方式就相当只要判断hash值的新增与运算的位是0还是1,就直接迅速算出扩容 后的存储方式。

3.在1.7中使用的是数组+单链表的数据结构,但是在1.8及以后,用的是数组+链表+红黑树的数据结构(当链表的深度达到默认阀值(8)的时候,就会自动扩容把链表转成红黑树的数据结构把时间复杂度从0(N)变成0=O(logN)提高效率)

 

八。1.8及以后为什么不用二叉树而用红黑树

选择红黑树是为了解决二叉查找树的缺陷,二叉树在特殊情况下会变成一条线性结构,遍历查找会非常慢,而红黑树是平衡二叉树,插入数据后通过左旋右旋变色来保持平衡。引用红黑树是为了查找数据快,但也会有资源损耗,所以要长度大于8才会使用红黑树

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值