手撕 JDK1.8 HashMap源码(上)

本文详细介绍了JDK1.8 HashMap的内部实现,包括其继承体系、Node数据结构、底层存储结构的演变(数组+链表+红黑树)、Hash碰撞和链化现象,以及为何引入红黑树来优化长链表查询性能。此外,还探讨了HashMap的扩容机制和负载因子,解释了为何选择0.75作为最佳值。通过对HashMap源码的剖析,帮助读者理解其工作原理和优化策略。
摘要由CSDN通过智能技术生成

手撕 JDK1.8 HashMap源码(上)

本文是对于HashMap源码的铺垫 并没有涉及到源码
源码篇:手撕 JDK1.8 HashMap源码(下)

基础入门

什么是哈希

核心理论:Hash也称散列、哈希,对应的英文都是Hash。基本原理就是把任意长度的输入,通过Hash算法变为固定长度输出。

这个映射的规则就是对应的Hash算法,而原始数据映射后的二进制串就是哈希值。

Hash的特点

  1. 从hash值不可以反向推导出原始的数据

  2. 输入数据的微小变化会得到完全不同的hash值,相同的数据会得到相同的值

  3. 哈希算法的执行效率要高效,长的文本也能快速的计算出哈希值

  4. hash算法的冲突概率要小

由于hash的原理是将输入空间的值映射成hash空间内,而hash值的空间远小于输入的空间。

根据抽屉原理,一定会存在不同的输入被映射成相同输出的情况。

抽屉原理:桌子上有十个苹果,要把这十个苹果放到九个抽屉里,无论怎样放,我们发现至少会有一个抽屉里面放不少于两个的苹果,这一现象就是我们所说的“抽屉原理”。

HashMap原理讲解

1. HashMap的继承体系

// HashMap继承AbstractMap
public class HashMap<K,V> extends AbstractMap<K,V>
// AbstractMap实现Map
public abstract class AbstractMap<K,V> implements Map<K,V>

image-20220416165009633

2. Node数据结构分析

// put到Map里面的数据都会被封装为一个Node<K,V>存放到散列表当中
static class Node<K,V> implements Map.Entry<K,V> {
        final int hash; // K.hash()经过一次扰动
        final K key;
        V value;
        Node<K,V> next; // hash碰撞 链表的next指针

3. 底层存储结构介绍

jdk1.8之前,由 数组+链表 组成。

jdk1.8开始,由 数组+链表+红黑树 组成。

image-20220416165918907

4. put数据原理分析

image-20220416171208553

5. 什么是Hash碰撞

进行路由寻址之后计算的下标index相同,即出现Hash碰撞

6. 什么是链化

由于Hash碰撞,从而形成链表

image-20220416172639239

7. jdk8为什么引入红黑树

链化非常严重,链表过长,查询时间复杂度由 O ( 1 ) → O ( N ) O(1)→O(N) O(1)O(N),故引入红黑树解决。

8. HashMap扩容原理

空间换时间

  • 负载因子 0.75

负载因子指的是什么呢?当我们要存10000个数据时,每一个哈希桶都会存好几百个数据,那么每一个哈希桶的链表长度都很长,它的性能会变得很低,即使它会优化成红黑树;负载因子 0.75 的含义就是当我们所有的桶已经有 75% 的桶都存上数据时,会对桶的数量进行扩容,桶会变得更多,它的扩容大小就是原长度的 2 倍,默认是16,从16扩容成了32,当然取余操作也要变成%32。

经官方测试 负载因子的 0.75 就是最佳值,如果负载因子是0.5,那么你的哈希桶永远只能存一半,但是它的占用空间大,效率高;如果给到0.99,那么这个哈希桶空间浪费的特别少,但是找数据就会比较慢。

API文档中的叙述:

image-20220410150927812

文章参考:b站小刘讲源码视频

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小成同学_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值