【八股文】HashMap相关考点

1.HashMap的底层是用什么实现的?

答:jdk1.7之前是用的数组+链表,jdk1.8之后是数组+链表+红黑树。追问
1.1 为什么会用红黑树?
答:当多个键的哈希值散列到同一个数组的位置时,查询,插入和删除的时候会退化到O(N)的复杂度,而如果用红黑树会将查询,插入和删除的复杂度降低到O(logN)。为什么红黑树能够做到这一点,是因为红黑树又叫自平衡的二叉搜索树。而二叉搜索树满足左边节点都小于根节点,右边节点都大于根节点的值。为什么要自平衡,如果不自平衡,可能会出现一种极端的情况,比如说左斜树或右斜树的情况。自平衡是将树的高度自平衡到logN的高度。
1.2红黑树的性质?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DZgdHHo1-1722445301372)(https://i-blog.csdnimg.cn/direct/2be8f4096145452f892683515e46a426.png)]
答:性质1:节点要么是红色的,要么是黑色的
性质2:根节点是黑色的
性质3:叶子节点都是黑色的空节点
性质4:红色节点的子节点都是黑色
性质5:从任一节点到叶子节点的所有路径都包含相同数目的黑色节点
在添加和删除节点时,如果不符合这个性质,就开始旋转,来保证平衡
1.3 jdk1.8还做了哪些改进?
答:解决了1.7情况下的多线程死循环问题,在jdk1.7的HashMap中在数组进行扩容的时候,因为链表用的是头插法,在进行数据迁移的过程中,有可能导致死循环。
比如说:现在有两个线程
线程一:读取到当前的HashMap数据,数据中一个链表,在准备扩容时,线程二介入
线程二:也读取HashMap,直接进行扩容。因为是头插法,链表的顺序会进行颠倒过来。比如原来顺序是AB,扩容后的顺序是BA,线程二执行结束。
线程一:继续执行的时候就会出现死循环问题。
线程一先将A移入新的链表,再将B插入到链头,由于另外一个线程的原因,B的next指向了A,所以B->A->B形成死循环。当然,JDK 8 将扩容算法做了调整,不再将元素加入链表头(而是保持与扩容前一样的顺序),使用尾插法避免了jdk7中死循环的问题。

2.HashMap的扩容机制?

当链表长度>=8时,先判断当前数组的长度是否小于64,如果小于则先进行数组扩容,如果大于则将链表转化为红黑树。HashMap的初始值为16,每次扩充是原来的2倍。追问
1.1 什么时候进行数组扩容?
HashMap里有一种负载因子loadFactor,loadFactor约接近1,存放到数组中的元素就越多,导致查找速率较低。如果loadFactor越小,存放到数组中的数据就越小,所以底层默认的是0.75。数组大小默认值是16,如果达到16*0.75=12时就开始扩容,扩容到32.
1.2 什么时候红黑树会退化成链表?
当红黑树的节点经过一系列删除操作后,如果该树上的节点数量减少到了不足以维持红黑树结构的最小限度,即当节点数量少于某个阈值时(6),它会重新退化成链表。
扩容流程如图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dDs2VXIA-1722445301373)(https://i-blog.csdnimg.cn/direct/47e5191476f94f7da2d58c950bdbb8f9.png)]
更新中。。。

参考

黑马程序员面经

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
HashMap是Java集合框架中的一个重要类,用于实现键值对的存储和检索。下面是关于HashMap八股文: 1. HashMap是基于哈希表的数据结构,通过键来进行快速的存取操作。它实现了Map接口,不允许键重复,但允许值重复。 2. HashMap采用数组+链表/红黑树的方式来存储数据。当发生哈希冲突时,会使用链表或红黑树解决冲突问题。链表适用于存储冲突较少的情况,而红黑树适用于存储冲突较多的情况。 3. HashMap的键和值可以为任意类型的对象,但键不能为null(HashMap中只允许一个键为null),值可以为null。如果多次放入相同的键,则会覆盖之前的值。 4. HashMap内部使用哈希函数将键转换为对应的数组下标,这个过程称为哈希计算。通过哈希计算,可以快速定位到对应的数组位置,从而提高存取效率。 5. HashMap的初始容量和负载因子是影响性能的重要参数。初始容量指定了哈希表的大小,负载因子指定了哈希表在发生重新哈希之前可以达到多满的程度。 6. HashMap的put方法用于向集合中添加键值对,get方法用于根据键获取对应的值。通过hashCode和equals方法来判断键的相等性。 7. HashMap是非线程安全的,如果在多线程环境下使用HashMap,需要进行外部同步控制或使用线程安全的ConcurrentHashMap。 8. 在遍历HashMap时,可以使用迭代器或者通过键集、值集或键值对集来进行遍历。要注意,在遍历过程中修改HashMap可能会导致ConcurrentModificationException异常。 这些是关于HashMap八股文,希望对你有所帮助!如有疑问,请继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星空皓月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值