关于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.

评论 57
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IT派同学

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

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

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

打赏作者

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

抵扣说明:

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

余额充值