哈希表概述

本文详细介绍了Java中的HashMap数据结构,包括对象数组+链表的组合,以及在JDK1.8中引入的红黑树优化。当链表长度达到8时,HashMap会将链表转换为红黑树以提升查找效率。此外,讨论了哈希表的初始容量、散列因子0.75以及如何在数据量达到75%时进行扩容。哈希表的性能优化还包括适时的扩容策略,以平衡空间利用率和查找速度。
摘要由CSDN通过智能技术生成

哈希表—HashMap

Map集合的子类,HashMap

Java中对于HashMap的数据结构,是采用对象数组+链表,在链表长度达到一定长度会转换成红黑二叉树;

讲哈希表之前,我们先来看一下API中的Object.hashCode

image-20220410131739512

既然这个方法是属于Object类的,那就说明所有的类也都有hashCode()这个方法,所有对象都可以调用这个方法,返回对象的哈希码值。

image-20220410132319240

支持此方法的优点是散列表,例如HashMap中的散列表。

这里的支持此方法,指的是你的编写的子类重写了hashCode()方法,优点是对散列表的性能进行的优化,散列表就是我们的哈希表

首先public int hashCode()返回的是一个int值,它的作用是什么,为什么说hashCode()可以提高哈希表的性能,原因很简单,哈希表的结构是这样的:

image-20220410135009580

这种存储的效果有多好呢?如果我们要找一个数据,我们不需要对整个数组进行遍历,我们只需要得到它的哈希值进行取余操作,就可以得到它所在的下标,根本不需要遍历就可以很快的找到我们想要的数据。

假设我们还有一个对象的哈希值进行取余后也等于1,那我们应该把它放在哪里呢?我们的哈希表是数组+链表,也就是说一个下标不仅仅只能存一个值,我们把这些值以链表的形式链起来, O b j e c t → O b j e c t Object→Object ObjectObject,俗称拉链法

image-20220410142247667

当一个对象要存在1下标时,先看一下1下标里有没有数据,如果没有则直接存在链表的根节点,如果有一个数据则存在根节点的下一节点,以此类推;

jdk1.8版本时对哈希表进行了优化,当我们的一个下标中存储的数据达到了 8 8 8 个,再存储就会达到 9 9 9 时,也就是当一个数组的某一个下标的链表的长度超过 8 8 8 时,链表会转换成红黑树的形式,链表 → → 红黑树,它会更利于查找;

当然数组里面的每一个下标也有一个名词,它被称为哈希桶

所以完整的阐述:

当哈希桶中的数据量超过8时,从链表转换为红黑树(且数组长度 > 64,如果数组长度不大于64则对哈希桶数量扩容)

当哈希桶中的数据量减少到6时,从红黑树转换回链表

有的面试官很喜欢给你挖坑,他会问你:此时一个哈希桶中已知的数据量为7,那么当它减少到6时,一定会从红黑树转回链表吗?

大部分同学不思考直接下意识的就说出来,会!那么你就掉进坑里了!

因为此时我们的数据量可能从未到达过8,也就是一直以链表的方式存储,红黑树根本没有出现过,所以在描述的时候一定要把这种特殊情况描述出来。

以上就是哈希表的基础结构。

还有一些知识点:

  • 初始桶的数量 16
  • 散列因子 0.75

首先哈希桶的数量是会变化的,如果我们初始化时不给哈希桶的数量,那么它默认的数组长度就是16

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

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

API文档中的叙述:

image-20220410150927812
构造方法:

image-20220410154328076
以上就是Java实现的哈希表,还是比较复杂的,对于性能有各种方面的考虑;

但比较常用的哈希表就是创建一个数组 然后根据哈希值往某个下标存,这就是一个简易的哈希表。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小成同学_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值