超详细讲解java中的HashMap,附赠java架构师资料分享

什么是Hashmap

HashMap就是一个容器,用来存储数据,但是为什么不使用Arraylist,或者为什么不使用Link

数组的形式

超详细讲解java中的HashMap,附赠java架构师资料分享

link的形式

超详细讲解java中的HashMap,附赠java架构师资料分享

hashMap的形式

超详细讲解java中的HashMap,附赠java架构师资料分享

看到这里是不是有一种恍然大悟的感觉,hashMap其实就是数组加链表,我最开始的时候问过为什么不使用数组,

数组:使用数组你会发现他查询很快,但是增删改查效率非常低

链表:链表是非常快,但是对于增伤改查非常快,如果查询数组最好,并且链表非常消耗资源

Hashmap:而Hashmap出现就是结合了他们两个的优点※

提问问题

如果你把我下面的问题都会了,那说明你还不错哦,嘿嘿

1为什么使用hashcode?

2为什么会有数组,为什么用链表?

3什么时候扩容,如果进行扩容?

4什么时候使用使用红黑树?

5为什么hashcode要和节点进行与操作?

6数组长度多少,其他空间不可以占用,除非扩容?

7为什么判断hash和可以是否相等?

8整个体系的流程是什么?

代码

一般情况下我们都是这样使用HashMap

超详细讲解java中的HashMap,附赠java架构师资料分享

源码分析

为什么使用HashCode

你有没有想过一个问题,如果我们使用hashMap,我们的下角标是如何生成的,难道我们使用的是随机数生成的下角标吗?那谁知道数据长度得有多大啊,

  1. 得到一个节点,重点看hash(key)
超详细讲解java中的HashMap,附赠java架构师资料分享

2.你会发现hashCode会与做与运行把低16位于高16位进行异或运算,为什么会这么做呢,这么做的时候我们会把前16给取出转换为二进制与h进行异或运算,这样就避免了出现重复的值,如果出现重复的值,可能会出现其中一个链表很长,但是其他位置根本没有数据,所以要把其他的位置都用起来.

下面的操作就是计算node节点到底在数组的什么位置?

n-1 & hash =====>hash%n , 得到的是0-15的区间, n的默认大小是16

0010101011001010010100101001

01111

最终的结果肯定是在16范围之内的.为什么用与是因为&与操作效率比较高

超详细讲解java中的HashMap,附赠java架构师资料分享

3通过第二步的操作大家有没有感到疑惑,如果是第2步操作得到的是15,那么这个时候二进制变为01110,这个时候不满足16,导致分布不匀均,那么如果才能分布均匀,所以数组的大家都是2的n次幂

在最开始的时候我们就给定默认的值,所以这里的16是有原因的,与操作的时候才会分布均匀

超详细讲解java中的HashMap,附赠java架构师资料分享

当看到这个的时候你想到了什么,我最开始的时候说要使用hashCode,而hashCode也就是从整个地方过来的,但是你有没有发现当拿到key的hashCode的谁还会进行16位的与操作,为什么在找数组下标(与操作)之前会使用hashCode在进行本身的异或?

原因就是为了避免出现重复的数据,为了node在数组中的位置分布均匀才做的这个操作

超详细讲解java中的HashMap,附赠java架构师资料分享

让他们两个之间进行异或,得到最后的hashcode

0101001010010高16位

0101001001001低16位

初始化数组

在这里只是声明了数组,但是并没有给数组赋值

超详细讲解java中的HashMap,附赠java架构师资料分享

赋值语句

超详细讲解java中的HashMap,附赠java架构师资料分享
超详细讲解java中的HashMap,附赠java架构师资料分享
超详细讲解java中的HashMap,附赠java架构师资料分享

把数据放到指定位置

如果是第一次存放

超详细讲解java中的HashMap,附赠java架构师资料分享

如果是key和hash相等,所以你会发现他到最后返回的以前的value

超详细讲解java中的HashMap,附赠java架构师资料分享

如果使用红黑树

超详细讲解java中的HashMap,附赠java架构师资料分享

如果是在链表里

这个时候你会发现他其实就是循环链表,然后判断是否为空

超详细讲解java中的HashMap,附赠java架构师资料分享

如果这个时候链表的长度超出我们设置的链表长度8-1,那么这个时候就分配红黑树

超详细讲解java中的HashMap,附赠java架构师资料分享

什么时候扩容

看到这的时候大家有没有疑问,有没有想过数组长度只让用到75%,那么他怎么知道是不是需要扩容呢?

超详细讲解java中的HashMap,附赠java架构师资料分享

当他的size大于了threshold就会进行扩容,执行resize()操作,最开始我们进行数组初始化的时候也是执行的resize()操作

超详细讲解java中的HashMap,附赠java架构师资料分享

他首先会判断你是否大于0 ,如果大于0,再判断是否大于最大值

超详细讲解java中的HashMap,附赠java架构师资料分享
超详细讲解java中的HashMap,附赠java架构师资料分享

链表可以无限的伸展吗

你有没有想过这个问题? 假如hashmap的其中有一个位一直有node,那么这个时候会无限的向链表中添加数据,那么这个时候链表的数据就会变得很长,所以非常不好, 解决方案是设置规定的值

链表的长度不可以超过8

超详细讲解java中的HashMap,附赠java架构师资料分享

写在最后:柠檬为大家准备了一些java学习教程。适合于1-5年开发经验的java程序员面试涉及到的绝大部分面试题及答案做成了文档和学习笔记文件以及架构视频资料免费分享给大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术资料),希望可以帮助到大家。

超详细讲解java中的HashMap,附赠java架构师资料分享
超详细讲解java中的HashMap,附赠java架构师资料分享

获取方式:请大家关注并私信小编关键词:“资料”即可获取你需要的各类资料。

相关推荐