hashMap和HashSet的put()操作

本文深入探讨HashMap和HashSet的put()操作。HashMap基于哈希表实现,内部使用Node类存储元素,当达到一定负载因子时会进行扩容。HashSet依赖HashMap,利用put()方法插入元素。当冲突发生时,可能转为红黑树。需重写hashCode()和equals()以确保正确存储。put()方法涉及节点创建、位置查找、冲突解决等步骤。
摘要由CSDN通过智能技术生成

hashMap和HashSet的put()操作

1.1、底层

hashMap和Map底层是哈希表结构,HashSet也是用到了HashMap的put()操作

哈希表是数组+链表+红黑树组成

1.2、前提了解
1.2.1、

在这里插入图片描述

成员变量,这个是节点数组,存储链表的数组,默认初始长度为16

1.2.2

在这里插入图片描述

resize()方法是调整节点数组长度大小的方法,默认数组长度是16,加载因子为0.75,单存储到16*0.75 = 12个元素的时候会进行扩容,扩容到原来的2倍长度为32个数组长度

1.2.3

在这里插入图片描述

hash()方法是获取到hash值的方法,用到的是hashCode()这个方法,如果不重写,调用的就是Object类中的hashCode()方法,获取的就是根据地址值生成的hash值

1.2.4

在这里插入图片描述

节点Node类

1、hash为存储元素key的哈希值

2、key key值

3、value value值

4、next 下一个节点

1.3、put()源码查看
1.3.1

在这里插入图片描述

调用put()方法将调用putVal()方法,将hash值,key,value,false,true这5个参数传递进去

1.3.2

在这里插入图片描述

1、创建节点数组和节点

2、将当前节点数组table赋值给tab,tab等于空或者tab的长度为0都将会执行最后一句语句

3、如果条件判断成功,可以证明节点数组还没有给出默认大小,调用resize()调整数组长度大小(默认初始长度大小为16),在赋值给tab,将tab节点数组的长度大小赋值给n

1.3.3

在这里插入图片描述

1.3.4

else上面就是节点数组中找到了位置,该位置中还没有元素,那么就将元素存储进去

else下面就是找到了位置,并且位置上有元素,那么我们就要进行一系列的判断了,下面我们就具体分析else里面的内容

在这里插入图片描述

1.3.4.1、第一个判断内容分析
分析一:

在这里插入图片描述

分析二:

在这里插入图片描述

1、既然用到了红黑树,那么我们就要想tree中我们自己定义的规则,比较器排序和自然排序定义定义规则,那么Map中的红黑树是怎么定义规则的?

2、图中我们可以看到红黑树存储将hash值传递过去了,那么红黑树存储就是用hash值来进行存储

3、可以看到p强制转换为红黑树的类型

分析三:

在这里插入图片描述

1.3.4.2、第二个判断内容分析

在这里插入图片描述
返回的旧值,是给hashMap使用

1.3.5

在这里插入图片描述

if里面判断需不需要给数组扩容

返回的null是给hashSet来使用,接下来我们看hashSet里面的add方法,返回为null就代表添加成功

在这里插入图片描述

1.4总结

1、我们要使用hash就必须要重写hashCode()和equals方法

2、hashCode()方法是依据属性值来进行计算,equals是比较属性值是否一样

3、两个属性值相同的对象hash值也是一样的,他们会找到在节点数组中相同的位置存储,在调用equals方法进行属性比较,相同不会存储

4、不同属性值的对象可能会找到在节点数组中相同的位置存储

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值