哈希表概述

简介: 哈希表概述

哈希表概述

哈希值

万物都有哈希值

方法hashCode()就是返回一个对象的哈希值;这个方法属于Object类,Object类是万物的父类,所以也就是万物都有哈希值;

hashCode()返回的是int类型的值;

哈希表结构

哈希表的结构是对象数组+链表+二叉树的形式;

对象数组长度为16,元素下标为0-15,每个元素称之为哈希桶,也就是有16个哈希桶;

每个哈希桶的结构是链表加二叉树的形式;

哈希表存取数据

假如有个Object对象要存入哈希表中:

刚开使用**Object.hashCode()**得到一个int值的数据,然后int值%16(除16取余数),得到的值为多少,就存入对象数组对应下标的哈希桶中,并放在链表第一个位置,当又一个对象进入该哈希桶,该对象就放在链表第二个位置,以此类推;

当一个哈希桶中存的对象大于8个时,链表就会自动变为二叉树的存储形式;

当哈希桶中对象个数减少到6个时,二叉树又会变成链表结构;

散列因子

初始时对象数组长度为16;但是当散列因子>=0.75时,对象数组长度会扩容两倍;

散列因子:就是目前存储了对象的哈希桶占目前所有哈希桶的比例,0.75就是指有75%的哈希桶存储了对象;

当扩容到两倍时:下一次就是除以32取余了(如果之前是除16取余)

HashMap存储数据:

HashMap存储的是键值(K V)的数据;

计算出K的哈希值,然后进行取余运算:(n-1) & hash:表示K的哈希值hash除以对象数组长度取余;

当该哈希桶没有数据,就创建一个新节点存入该键值对;

如果哈希桶已经有数据,就拿要存的数据的K和哈希桶里面的K一一比对,如果K一样,就用新的V覆盖旧V并返回旧V,如果K不一样则存存在最后的节点上;

当我们向HashMap中插入一个键值对时,会首先调用键对象的hashCode()方法,得到该键的哈希值。这个哈希值会被用来定位这个键值对在HashMap内部存储的位置。

然后,HashMap会根据得到的哈希值进行模运算,计算出一个数组下标。HashMap内部实际上是使用了一个数组来存放所有的键值对,这个数组的长度默认为16,并且会随着元素的增加而自动扩容。

接下来,根据计算出来的数组下标,我们会找到对应的位置。但是,这并不意味着我们就可以将键值对直接存放在这个位置,因为不同的键可能会产生相同的哈希值,这就会导致多个键值对被存放在同一个位置,这种情况被称为哈希冲突。

 

为了解决哈希冲突的问题,HashMap采用了链表和红黑树两种方式来存储同一下标的多个键值对。当我们插入第一个键值对时,会在对应位置创建一个链表节点,并将键值对存入。当我们继续插入具有相同哈希值的键值对时,会在链表的尾部添加新的节点。当链表的长度超过一定的阈值(默认为8),链表就会转化为红黑树,以提供更高效的查询性能。

当我们需要从HashMap中获取一个键对应的值时,会先计算出键的哈希值,然后根据哈希值找到对应的位置,然后在该位置上的链表或红黑树中查找对应的键值对。

这就是HashMap存储数据的基本流程,通过哈希化的方式,将键映射到一个固定大小的空间内,再通过链表或红黑树的方式来处理哈希冲突,使得HashMap能够在不同的场景下都能提供稳定的性能表现。

需要注意的是,虽然HashMap提供了高效的存取操作,但是它并不是线程安全的。如果在多线程环境下需要使用HashMap,建议使用Collections.synchronizedMap方法将其包装成线程安全的版本,或者使用ConcurrentHashMap等线程安全的数据结构。

HashMap以其高效、灵活的特性,成为了我们在编程过程中最常用的数据结构之一,深入理解其存数据的流程,对于我们更好地利用这一工具,提高程序的性能具有重要意义。

 

相关文章
|
7月前
|
存储 索引
什么是哈希表?它的工作原理是什么?
在我们的日常生活中,我们经常需要存储和查找各种信息,这些信息可能是电话号码,地址,或者是商品的价格等等。这些信息的存储和查找,就像是我们在一个巨大的仓库中存放和寻找物品。这个仓库就是数据结构,而其中一个最常用的,也是最高效的数据结构就是哈希表。
106 2
|
2月前
|
数据安全/隐私保护 索引
第三章 哈希表
第三章 哈希表
32 1
|
4月前
|
存储 Java
数据结构中的哈希表(java实现)利用哈希表实现学生信息的存储
这篇文章通过Java代码示例展示了如何实现哈希表,包括定义结点类、链表类、数组存储多条链表,并使用简单的散列函数处理冲突,以及如何利用哈希表存储和查询学生信息。
数据结构中的哈希表(java实现)利用哈希表实现学生信息的存储
|
7月前
|
存储 算法 Java
【算法系列篇】哈希表
【算法系列篇】哈希表
|
6月前
|
存储
哈希表的设计与实现
哈希表的设计与实现
50 1
|
7月前
|
算法 C++
c++算法学习笔记 (20) 哈希表
c++算法学习笔记 (20) 哈希表
|
7月前
一道题学会如何使用哈希表
一道题学会如何使用哈希表
|
7月前
|
存储 算法 Java
算法系列--哈希表
算法系列--哈希表
42 0
|
存储 缓存 算法
趣味算法——探索哈希表的神秘世界
前言: 在编程世界中,数据存储和检索的效率常常是我们关注的重点。对于这个问题,哈希表提供了一个既高效又实用的解决方案。哈希表是一种通过哈希函数将键转化为数组索引,以实现快速查找的数据结构。在大多数情况下,哈希表能够在常数时间内完成查找,插入和删除操作,因此在许多应用场景中得到了广泛使用。
72 0
|
存储 缓存 算法
【C++进阶】九、哈希表
目录 一、哈希概念 二、哈希冲突 三、哈希函数 四、哈希冲突解决 4.1 闭散列(开放定址法) 4.1.1 线性探测 4.1.2 二次探测 4.1.3 研究表明 五、哈希表的闭散列实现 5.1 闭散列哈希表的结构 5.2 闭散列的插入 5.2 闭散列的查找 5.3 闭散列的查找 5.4 哈希表取模问题 5.5 string类型无法取模问题 5.6 完整代码 四、哈希冲突解决 4.2 开散列(链地址法、哈希桶) 六、哈希表的开散列实现(哈希桶) 6.1 哈希桶的结构 6.2 哈希桶的插入 6.3 哈希桶的查找 6.4 哈希桶的删除 6.5 完整代码
123 0
【C++进阶】九、哈希表