Map集合之HashMap细说

最近在看面试题,看到了hashmap相关的知识,面试中问的也挺多的,然后我这里记录下来,供大家学习。

Hashmap为什么线程不安全

  • jdk 1.7中,在扩容的时候因为使用头插法导致链表需要倒转,从而可能出现循环链表 问题或者数据丢失的问题

  • jdk 1.8中,在put方法中,假设A,B两个线程都插入相同的值到同一个下标,这个下标对应的值此时为null,假设线程A进行方法后挂起,而线程B顺利执行,此时该下标对应的值为B插入的值,然后A线程获得时间轮,此时线程A不再进行hash判断了,直接进行插入,就会导致覆盖了原来B插入到该下标的值

HashMap类(底层为数组+链表+红黑树)

扩容机制

在java8以后,满足扩容机制的只需要笑傲一个条件即可,即当加入的新的数据和其他数据大于或者等于阈值就会发生扩容,且这种扩容形式也是在先插入新值后,再进行扩容。

在java7中,每个节点存放一个Entry,每个Entry后面跟着一个链表,链表的每个节点存放一个Entry,这个Entry上保存有相应的key/Value,且存放着下一个节点的地址;在java8之后,因为引入了红黑树,所以把Entry改成了Node,其他的存放的内容都和Entry上面存放的一样。

但是,在java8后虽然底层结构变成了数组+链表+红黑树,但是不一定会用到红黑树,只有当总的数据量大于64或者链表长度大于8的时候会将链表转换为红黑树。

扩容满足的条件(什么时候扩容)

在java7中,扩容需要满足以下两个条件(任意一个满足都会发生扩容)

  • 存放当前元素前,数据个数大于等于阈值

  • 存放当前元素时发生hash冲突

在java8后,扩容只需要满足--》存放当前元素后,数据量大于等于阈值,且扩容是在插入新数据后进行扩容

为什么在JDK 1.8后hashmap底层要添加红黑树

当hash冲突过多的时候,数据插入到链表后面就会越来越多,就会导致链表链化严重,对于CRUD这些操作会造成较高的复杂度(O(n)),所以为了解决这一问题,在java8后使用红黑树来处理这种链化的情况。

hash冲突怎么解决

hash冲突表示的是当插入一个新值的时候通过hash函数计算出的下标值已经存入得对应数据,这个时候再插入一个值的时候就会出现hash冲突。

开放地址法
线性探测

根据hash函数计算下标值,如果当前下标已经有值存在,那就去判断下一个下标是否存值,通过这样的方式来解决hash冲突,但是这样的方式可能会引起聚集,即连续找了多次下标都是有值的情况,这样会在后续的操作中增加复杂度。

二次探测

即根据hash下标的二次方进行探测(1,4,9.......),这样的做法可以减少聚集的问题

双重散列

如果当前通过hash散列函数计算出的下标已经存入了值,那就在用另外的hash散列函数再次进行计算

链地址法

每一个hash桶后面都会跟着一个链表,当通过hash函数找到对应桶,如果当前值对应下标在链表中已经存入了值,那么就会将该值放在链表末尾然后进行存储。

再哈希

再哈希是指当前的哈希函数计算出来的下标值已经被占用,这时就会使用一个新的哈希函数来进行再次计算。

双重散列和再哈希的区别

双重散列和再哈希都是需要使用多个hash函数来解决hash冲突,但是对于双重散列而言,每一次的hash函数都是新的hash函数,不会根据前一个hash函数计算出来的下标值为基础进行计算,而再哈希的每一个hash函数会根据前一个hash函数计算出来的下标值为基础进行计算,这样对于下一次计算出来的下标肯定不会和前一个hash函数计算出来的下标相重合。

hashmap和hashtable的区别

  • hashmap是线程不安全的,而hashtable是线程安全的

  • hashmap可以存储null键和null值,hashtable不能存储null键和null值

  • hashmap在jdk1.8之后底层结构为数组+链表+红黑树,hashtable底层数据结构为数组+链表

以上为自己学习过程中列出来的知识点,当然还存在很多不足,各位有补充的可以在评论区进行留言我们共同学习~

相关推荐
冰帝海岸10 分钟前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象36 分钟前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了1 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
----云烟----1 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024061 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
小二·1 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic2 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
向宇it2 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
懒洋洋大魔王2 小时前
RocketMQ的使⽤
java·rocketmq·java-rocketmq
武子康2 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud