面试必问HahsMap原理

HashMap底层原理(自身体会)

面试必问hashMap原理

1、ArrayList底层是基于动态数组的:查询快,增删改慢;

2、LinkedList底层是基于双向链表的:查询慢,增删改快;

3、有没有一种查询和增删改比较平衡的方式: hash结构=数组+单向链表

4、hashMap底层就是采用的这种hash结构;

5、hashMap类里边包含属性:Entry[] tables; Entry 对象;

6、Entry 对象(Object key,Object value,int hash,Entry next)

7、当我们给HashMap里边添加1个键值对时:(k,v)

8、首先创建1个Entry对象,k,v放进去,把k,进行单向散列计算(hash算法),得到一个int类型的hash值。

9、创建1个Entry[] tables数组,默认长度是16;

10、用hash值对16进行求模,余数是几,就把这个创建好的Entry对象放到Entry[] tables数组的对应位置;

11、如果再给hashMap里边,添加第2个值,同样先创建Entry对象,根据k,计算hash,然后对16求余,放到对应位置;

12、但是:比如第1个值hash是17,放在了数组的下标为1的位置,现在又添加了1个值,hash值是33,对16求余也是1; 也要往1的位置放,但是数组1的位置已经有值了。 这就叫做产生了hash冲突(hash碰撞);

13、如何解决hash冲突(hash碰撞): hashmap里边采用的方式是拉链法。首先把原来17的对象,set到33对象的entry里边,然后把33直接放到数组1这个位置;

14、随着放的值越来越多,数组单个位置的长度会越来越长,数组查找比较快,但是列表查找比较慢。所以为了保证查询速度,当里边存放值多时,会对数组进行扩容; 当操作0.75倍时,也就是16个位置,
已经有12个有值了,再有就进行扩容;自动扩容到之前的2倍;

15、扩容是一个效率比较低的操作,所以如果可以提前预估到hashmap中要存放数据的数量,
可以提前给他开辟比较大的空间,从而减少扩容;new HashMap(数组大小);但是注意:
数组大小为了保持高效,必须是2的n次方;即使你传了比如:66,会自动开辟128的空间,而不是66;

16、上述是jdk在1.7之前(包含1.7)的实现;而在jdk1.8以后,做了进一步的优化:
在单个hash槽的位置,这个链表长度超过8时,会自动转换成红黑树;
红黑树是一个有序平衡二叉树,他的查找时间复杂度:O(logn);比链表的O(n)要快很多;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值