关于HashMap的面试题,来看看你都知道哪些

🏡  博客首页:派 大 星

⛳️  欢迎关注  ❤️ 点赞  🎒 收藏  ✏️ 留言

🎢  本文由派大星原创编撰

🚧  系列专栏:《迎战面试》

🎈  本系列分享自己准备面试的过程和一些经典的面试题

🥞 HashMap和HashTable的区别?

  • HashMap是非线程安全,而HashTable是线程安全的
  • HashMap效率较高,而HashTable效率较低低
  • HashMap可以存放key为null值,而HashTable不允许存放key为null值

为什么这么说呢?让我们到源码中一探究竟:

由图中可以看出,在HashMap中的put方法中并没有synchronized锁,属于线程不安全的,而HashTable中的put方法含有synchronized同步锁来保证在进行操作的过程 中线程是安全的。但是在多线程的条件下访问到HashTable下的put方法时最终结果会变成单线程,那么必然会存在一个问题,即—效率问题;紧接着再进行探究是否可以存放null值,进入源码:
在这里插入图片描述
HashTable为例:由上图可以发现HashTable中的put()方法的执行逻辑,首先判断valuenull如果是则抛出空指针异常,然后再对key值进行hashCode取值计算,从而获取tab[]在某下标下的值并返回,从测试中得出最终结果:
在这里插入图片描述

结论:当存入key值为null时,则无法通过key.hashCode()从而计算出具体下标所对应的值,所以在HashTable中的key不能为null值,而在HashMap中的key则可以存放null值。那么HashMap既然是允许存放key=null,那么存放在数组的哪个位置呢?index= 0

🥗 简述Java中的HashMap

注:HashMap集合底层是使用Entry对象去封装键值对的

JDK8之前底层实现时数组+链表,JDK8改为数组+链表/红黑树。主要成员变量包括存储数据的table数组元素数量size、加载因子loadFactor

HashMap中数据是以键值对的形式存在,键对应的hash值用来计算数组下标的,如果两个元素keyhash值一样,就会发生哈希冲突,被放到同一个链表上。

table数组记录HashMap的数据,每个下标对应一条链表,所有哈希冲突的数据都会存放到一条哈希链表,Node/Entry节点包含四个成员变量:keyvaluenext指针hash值,在JDK8后链表超过8会转化为红黑树。

若当前数据/总数据容量 > 负载因子,那么HashMap将会执行扩容操作

默认初始化容量为16,扩容容量必须是2的幂次方,最大容量为1<<30,默认的加载因子为0.75

🥙 如何解决Hash冲突的问题

  • 使用链地址法(使用散列表)来链接拥有相同的hash值的数据

在Java中,保存数据有两种比较简单的数据结构:数组和链表。数组的特点是:寻址容易,插入和删除困难;链表的特点是:寻址困难,但插入和删除容易;所以将数组和链表结合在一起,发挥两者各自的优势,使用一种叫链地址法的方式可以解决哈希冲突。

在这里插入图片描述

  • 使用2次扰动函数(hash函数)来降低哈希冲突的概率。使得数据分布更平均

hashCode取值出的高位也参与运算,进一步降低hash碰撞的概率,使得数据分布更平均,我们把这种操作称为扰动

static final int hash(Object key){
  int h;
  //与自己右移16位进行异或运算(高低位异或)
  return (key == null)? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

JDK8中,只进行了1次位运算和1次异或运算(2次扰动)

  • 引入红黑树进一步降低遍历的时间复杂度,使得遍历更快

JDK8在HashMap中新增了红黑树的数据结构,进一步使得遍历复杂度从O(n)降低至O(logn)
在这里插入图片描述

🍲 为什么重写equals方法的时候还要重写hashCode方法

HashMapvalue的查找是通过keyhashCode来查找,所以对自己的对象必须重写hashCode方法通过hashCode找到对象地址后会用equals比较你传入的对象和HashMap中的key对象是否相同,因此还要重写equlas.

  • 40
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 57
    评论
回答: HashMapJava中的一个常用数据结构,它的底层是由hash数组和单向链表实现的。每个数组元素都是一个链表,通过Node内部类实现了Map.Entry接口来存储键值对。HashMap通过put和get方法来存储和获取数据。\[1\] 在重写equals方法时,我们需要同时重写hashCode方法。这是因为在HashMap中,查找value是通过key的hashCode来进行的。当找到对应的hashCode后,会使用equals方法来比较传入的对象和HashMap中的key对象是否相同。因此,为了保证正确的查找和比较,我们需要同时重写equals和hashCode方法。\[2\]\[3\] HashMap在什么时候进行扩容呢?当HashMap中的元素数量超过了负载因子(默认为0.75)与当前容量的乘积时,就会进行扩容。扩容是为了保持HashMap的性能,因为当元素数量过多时,链表的长度会变长,查找效率会下降。扩容的过程是创建一个新的数组,将原数组中的元素重新分配到新数组中,然后将新数组替换为原数组。\[3\] #### 引用[.reference_title] - *1* *2* *3* [史上最全Hashmap面试总结,51道附带答案,持续更新中...](https://blog.csdn.net/androidstarjack/article/details/124507171)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IT派同学

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

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

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

打赏作者

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

抵扣说明:

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

余额充值