HashMap源码分析,常用api介绍


)

1 HashMap实现原理

HashMap是基于拉链法实现的哈希表(散列表),内部由数组、链表、红黑树实现。
1、数组初始容量默认为16,以2的次方扩充;一是使用足够大的数组防止出现碰撞提高性能,二是为了使用位运算取代模运算。
2、是否需要扩充由负载因子控制,默认0.75,当元素个数到达容量的0.75时就会扩充,可由构造方法传入,越大性能越低空间占用越小,越小性能越高空间占用越高。
3、发生碰撞时,元素改为单向链表类型。当链表长度大于8时,转为红黑树;当链表长度小于6时,转为普通链表。在转换为红黑树之前会先判断一下是否达到阀值,如果达到会先扩充数组。

2 构造方法(注释有解释)

1、 无参(默认初始大小,负载因子)
在这里插入图片描述
2、 一个参数(设置初始大小、默认负载因子)
在这里插入图片描述
3、 两个参数(设置初始大小、设置负载因子)
会调用tableSizeFor方法,调用目的见下方
在这里插入图片描述
4、 一个参数(参数为map对象)
会调用putMapEntries方法,putMapEntries见下方,将传入map的数据复制到当前map中。
在这里插入图片描述

3 tableSizeFor方法

通过构造方法指定初始容量,但是容量必须为2的次方(位运算取代模运算),tableSizeFor就是进行实际初始容量的计算。
其原理为:将0 补为 1,最后进一位(+1),减1的这个动作为了避免16这种不需要加1的值(及其他2的次方同理)。
在这里插入图片描述
以12为例:只列出右移一位、两位的运算,移位按位或运算为15,加1后位16.
在这里插入图片描述

4 putMapEntries (Map<? extends K, ? extends V> m, boolean evict)方法

将一个map,批量添加到当前map中,此方法,在构造方法入参为map时,调用putAll时,调用clone时调用。
在这里插入图片描述

5 put方法/putVal方法

调用hash()获取key的hashcode见下方,resize()方法扩容,见下方
在这里插入图片描述
在这里插入图片描述

6 hash方法(异或运算)

在这里插入图片描述
取hashcode进行高位异或运算,在性能、实用性、分布质量上取得一个平衡。(数据均匀分布,减少碰撞发生)
例如:name作为key时,hashcode为3373707,右移16位后位51,异或运算后位3373752
在这里插入图片描述
在这里插入图片描述

补充:位运算

在这里插入图片描述

7 resize方法(扩容)

(1) 首先进行原数据、参数的copy
(2) 进行扩容判断,对于不需要扩容的直接返回
(3) 对扩容后的,进行数据迁移(红黑树未做介绍)
在这里插入图片描述
在这里插入图片描述

8 get/ getNode方法(取值)

get时,不存在或实际存储的值为null,都会返回null
在这里插入图片描述

9 remove/ removeNode方法(移除)

移除map中的属性
在这里插入图片描述
在这里插入图片描述

10 clear方法(清空)

只是把table[i]的数据置为null,执行效率比不上new一个新的map
在这里插入图片描述
在这里插入图片描述

11 clone方法(克隆)

在这里插入图片描述

12 containsKey方法(是否存在key)

getNode()见get方法
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HashMap 是 Java 中非常重要的数据结构之一,它实现了 Map 接口,提供了快速的键值对的查找和存储功能。下面是 HashMap分析: 1. 数据结构 HashMap 内部实现了一个数组,每个数组元素是一个单向链表,称为桶(bucket)。当我们向 HashMap 中添加一对键值对时,会根据键的哈希值(hashcode)计算出该键值对应该存储在哪个桶中。如果该桶中已经有了该键值对,就将该键值对添加到桶的末尾(Java 8 中是添加到桶的头部),否则就创建一个新的节点添加到桶的末尾。 2. 哈希冲突 如果两个键的哈希值相同,就称为哈希冲突。HashMap 采用链表法解决哈希冲突,即将哈希值相同的键值对存储在同一个桶中,通过单向链表组织起来。当我们根据键查找值时,先根据键的哈希值找到对应的桶,然后遍历该桶中的链表,直到找到目标键值对或者链表为空。 3. 扩容机制 当 HashMap 中的键值对数量超过了桶的数量的时候,就需要对 HashMap 进行扩容。扩容会重新计算每个键值对的哈希值,并将它们存储到新的桶中。Java 8 中,HashMap 的扩容机制发生了一些变化,采用了红黑树等优化方式。 4. 线程安全 HashMap 是非线程安全的,如果多个线程同时操作同一个 HashMap,就有可能导致数据不一致的问题。如果需要在多线程环境下使用 HashMap,可以使用 ConcurrentHashMap。 以上就是 HashMap分析,希望对你有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值