你真的懂HashMap吗?

1.HashMap的结构和底层原理
HashMap是由数组和链表组合构成的数据结构,它的存储是key-value键值对的形式存储的。跟据key的Hash去计算index下标,也就是插入的位置。

2.为什么会出现链表?
数组的长度是有限的,哈希本身存在概率性,极端会出现俩个key会Hash到同一个值,就会出现链表。

3.在新的Entry节点是怎样插入链表中的?
Java8之前是采用头插,新来的值会代替原来的值,原来的值就会到链表当中。
Java8之后采用的是尾插(因为头插,多线程插入可能会出现循环链表,取值时出现——Infinite Loop)

4.HashMap的默认初始长度?
16 1<<4

5.HashMap是如何扩容的?
扩容:创建⼀个新的Entry空数组,⻓度是原数组的2倍。
ReHash:遍历原Entry数组,把所有的Entry重新Hash到新数组。
负载因子0.75f,假如长度为100,当插入76个数据的时候就要进行扩容了
随着数组的长度改变,hash规则也将改变,所以需要hash而不是复制

6.Java8之后是不就可以把HashMap用到多线程当中了?
虽然不会出现循环链表取不到值,但是在源码当中put/get没有加同步锁,意味着上一秒put的值下一秒get的还是原值,线程的安全无法保证。

7.为什么不直接写16长度,而是采用位运算符?
提高性能
实现hash的均匀分布

8.为啥我们重写equals⽅法的时候需要重写hashCode⽅法呢?
因为在java中,所有的对象都是继承于Object类。Ojbect类中有两个⽅法equals、hashCode,这两个⽅法都是⽤来⽐较两个对象是否相等的。在未重写equals⽅法我们是继承了object的equals⽅法,那⾥的 equals是⽐较两个对象的内存地址,显然我们new了2个对象内存地址肯定不⼀样。
对于值对象,==⽐较的是两个对象的值
对于引⽤对象,⽐较的是两个对象的地址
HashMap是通过key的hashCode去寻找index的,那index⼀样就形成链表了,我们去get的时候,他就是根据key去hash然后计算出index,找到了2,里面有不同的key,我们取哪个呢??所以如果我们对equals⽅法进⾏了重写,建议⼀定要对hashCode⽅法重写,以保证相同的对象返回相同的hash值,不同的对象返回不同的hash值。不然⼀个链表的对象,你哪⾥知道你要找的是哪个,到时候发现hashCode都⼀样,这不是完犊⼦嘛。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

戏子 丶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值