2021最新HashMap面试题

本文详细探讨了HashMap的底层实现,包括其在JDK1.7和1.8后的数据结构变化,以及put和get操作的实现细节。在put操作中,通过键的hashcode计算存储位置,处理哈希碰撞,并在达到特定条件时进行扩容。get操作通过哈希函数快速定位,若存在冲突则遍历解决。此外,文章还讨论了负载因子的作用、何时触发扩容以及为何引入红黑树来优化性能。对于HashMap的高效使用,建议在初始化时设定合适的容量。
摘要由CSDN通过智能技术生成

谈一下HashMap的底层原理是什么?

       jdk1.7前采用数组+链表结构,jdk8后采用数组+链表+红黑树的数据结构.我们通过put和get存储和获取对象.当我们给put方法传递键和值时,先对键进行hashcode()的计算来得到它在bucket数组中的位置来存储Entry对象.当获取对象时,通过get获取到bucket的位置,在通过键对象的equals()方法找到正确的键值对,然后再返回值对象

谈一下HashMap中put是如何实现的?

1.根据key的算出hashcode值

2.如果散列表为空时,调用resize()初始化散列表

3.如果没有发生碰撞,直接添加元素到散列表中去

4.如果发生了碰撞(hashcode值相同),进行三种判断

4.1若key地址相同或者equals后内容相同,则替换旧值

4.2如果不相等且是红黑数结构,就调用树的插入方法

4.3是链表结构,循环遍历直到链表中的某个节点为空,尾插法进行插入,插入之后判断表个数是否到达红黑树的阙值8;也可以遍历到有节点与插入元素的哈希值和内容相同,进行覆盖

5.如果HashMap容量大于阈值,则resize进行扩容

谈一下HashMap中什么时候需要进行扩容,扩容resize()又是如何实现的

扩容场景:

1.初始化数组table

2.当数组table的size达到阈值时 即size>load factor*capacity时,也是在putVal函数中

扩容实现过程:

1.通过判断旧数组的容量是否大于0来判断数组是否初始化过

(1)否的话进行初始化

初始化判断是否调用无参构造器

调用:使用默认的大小和阈值

不调:使用构造函数中初始化的容量,这个容量是经过tableSizeFor计算后的2的次幂

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值