java基础篇 - HashMap 理解Hash碰撞

article/2025/11/11 2:38:36

HashMap是大家都在用,面试的时候也经常会被考的考点,在这篇文章中说下HashMap的hash碰撞和减轻碰撞的优化。

1、什么是hash碰撞


在解释Hash碰撞之前先说一下hashmap的存储结构、添加和检索是怎么实现的


    1.1HashMap的存储结构

    ·    HashMap的存储结构是Entry数组+链表的结构,如下图

HashMap存储结构

 


注意:数组+链表的结构是在JDK7中的数据结构,JDK8中已经变成数组 +(链表或红黑树)的结构


1.2添加元素

           添加过程:

            1、通过key的hashcode调用hash()函数,计算出hash值,

            2、计算数组存储数据的下标 index =hash&(数组长度n-1)

            3、通过index得到数组中对应位置的链表,JDK7中将新节点插入到链表头,而JDK8插入到链表尾部

            HashMap添加元素还有一个知识点就是多线程不安全,扩容造成元素丢失或者链表闭环的问题,这个知识点不在这篇文章中详述。


1.3快速检索

           通过key查询value的过程:

            1、通过Key的hashcode调用hash()函数,计算出hash值,

            2、计算数组下标 index =hash&(数组长度n-1)

            3、通过index得到数组中对应位置的链表,遍历链表的Entry通过==对key进行比较得到对应的entry


知道HashMap的添加和查询过程,来看一下什么是Hash碰撞


1.4Hash碰撞是什么,Hash碰撞严重会有什么问题

    在HashMap的查询和添加过程中,绕不过去的是计算元素在数组的位置index,key的HashCode作为这个计算的基础。计算后的Hash值存在相同的情况,hash与长度取余的结果也有相同的情况,这个时候运算结果相同的两个对象就需要存储到同一个链表中,这就是HashMap中的Hash碰撞。

    这样会引起什么问题呢,碰撞严重的话,大量的元素都存储在一个链表中,检索过程中的第三步,遍历链表会耗费大量的时间,严重极端情况下会遍历所有元素,检索效率会很低。和HashMap快速检索的设计严重不符。



hash碰撞严重回来带查询效率问题,那么HashMap做了什么优化,来避免Hash碰撞呢



2、HashMap碰撞优化


HashMap减轻Hash碰撞主要做了两个方面的优化,

    1)提高hash的复杂度,减少相同hash的出现

    2)让元素尽量均匀的分部到数组中


    2.1提高hash复杂度

    看一下JDK8中hash()函数的代码

        static final int hash(Object key) {int h;return (key ==null) ?0 : (h = key.hashCode()) ^ (h >>>16);}

    很简单,将key的HashCode右移16位将高16位和低16位做异或运算,目的是让hash值得低16位也包含高16位的特性。

    这样做有什么好处呢,元素在数组的下标index =hash%数组长度n,当数组长度很短的时候,如初始状态下是16,如果两个key的HashCode低16位相同,不处理的话index计算结果相同。只要HashCode不同的话,计算后的hash低16位保证不会相同。增强了hash结果的复杂度。

    注意:JDK7中hash函数要比JDK8中复杂度高很多,所以7的计算结果减少hash碰撞的效果更好,那为什么8不增加复杂度反而降低复杂度呢。官方解释是,因为JDK8在链表存储的基础上增加了红黑树的存储方式,提高了碰撞引起的查询效率。应该是对红黑树的效率比较有信心。


    2.2让元素尽量均匀分部

        前边已经说过,数组的下标的计算是:

                                      index= hash&(数组长度n-1)

           用17作为长度n计算一下取余,7转成二进制是 0001 0001 ,hash&(0001 0001 -1) =hash&(0001 0000) , 类似 0100 1001 和0010 1111的hash就会发生碰撞。

          怎么解决这个问题呢,保证&运算中二进制数每一位都是1,也就是数组的长度保证是2的整数次幂,就不会出现分不到元素的情况了。

        所以HashMap中对的优化策略就是,数组的长度必须是2的整数次幂。


注意:在HashMap扩容这个过程中,元素数量达到loadFactor*capacity,数组会扩容到2的n+1次幂,这个时候,map中存储的元素数量是  2的n次幂*loadFactor,

也就是说只要loadFactor<1,那么HashMap的数组长度永远大于元素数量,所以我理解的HashMap是空间换时间的容器。


Hash碰撞的知识点都已经说完了,分享一个在hashMap中的函数,代码如下

static final int tableSizeFor(int cap) {int n = cap -1;n |= n >>>1;n |= n >>>2;n |= n >>>4;n |= n >>>8;n |= n >>>16;return (n <0) ?1 : (n >=MAXIMUM_CAPACITY) ?MAXIMUM_CAPACITY : n +1;}

返回结果是一个2的整数次幂


                                               如有遗错请留言,会尽快修改


http://chatgpt.dhexx.cn/article/9jS2voCT.shtml

相关文章

大白话解释hash碰撞是什么以及如何解决

一、Hash如何存数据 hash表的本质其实就是数组&#xff0c;hash表中通常存放的是键值对Entry。 这里的id是个key&#xff0c;哈希表就是根据key值来通过哈希函数计算得到一个值&#xff0c;这个值就是下标值&#xff0c;用来确定这个Entry要存放在哈希表中哪个位置。 二、Ha…

hash碰撞的概率推导(生日攻击生日问题)

1.关于hash碰撞 哈希碰撞是指&#xff0c;两个不同的输入得到了相同的输出&#xff1b; hash碰撞不可避免&#xff0c;hash算法是把一个无限输入的集合映射到一个有限的集合里&#xff0c;必然会发生碰撞&#xff1b; 2.碰撞概率的问题描述的其他形式 n个球&#xff0c;&…

Hash碰撞(冲突)的解决方案

hash算法就是&#xff0c;用同一个哈希函数计算&#xff1a; 两个相同的值&#xff0c;计算出的hash值一定相同&#xff0c; 两个不同的值&#xff0c;计算出的hash值可能不同&#xff0c;也可能相同&#xff0c;当相同时就是hash冲突 一、链式寻址法 也叫“拉链法”&#…

MD5 hash碰撞实现解密

目录 1.前言 2.MD5 hash单个碰撞解密 3.MD5 hash批量碰撞解密 1.前言 在日常渗透中,获取到后台密码往往是加密的,常见的就是MD5加密,常见的做法我们会使用在线网站去解密,常用的有cmd5,somd5,cmd5对于一些密文是要收费的,有时我们就想白嫖。 这时我们会用so…

哈希碰撞+mysql_HashMap之Hash碰撞冲突解决方案及未来改进

HashMap位置决定与存储 通过前面的源码分析可知&#xff0c;HashMap 采用一种所谓的“Hash 算法”来决定每个元素的存储位置。当程序执行put(String,Obect)方法 时&#xff0c;系统将调用String的 hashCode() 方法得到其 hashCode 值——每个 Java 对象都有 hashCode() 方法&am…

Hash碰撞概率

计算Hash冲突的概率 虽然已经很多可以选择的Hash函数,但创建一个好的Hash函数仍然是一个活跃的研究领域。一些Hash函数是快的,一些是慢的,一些Hash值均匀地分布在值域上,一些不是。对于我们的目的,让我们假设这个Hash函数是非常好的。它的Hash值均匀地分布在值域上。 在这…

HashMap之Hash碰撞

详细理解了Hash碰撞及处理方法 为什么会出现hash碰撞 在hash算法下,假设两个输入串的值不同,但是得到的hash值相同, 即会产生hash碰撞 一个很简单的例子: 假设你自己设计了一个计算hash的算法toHashValue(String). 是取的输入值的Unicode编码值(当然实际的情况会比这复杂很…

hashmap存储方式 hash碰撞及其解决方式

1.Map 的存储特点 在 Map 这个结构中&#xff0c;数据是以键值对&#xff08;key-value&#xff09;的形式进行存储的&#xff0c;每一个存储进 map 的数据都是一一对应的。 创建一个 Map 结构可以使用 new HashMap() 以及 new TreeMap() 两种方式&#xff0c;两者之间的区别…

Java Hash 碰撞

散列函数&#xff08;英语&#xff1a;Hash function&#xff09;又称散列算法、哈希函数&#xff0c;是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要&#xff0c;使得数据量变小&#xff0c;将数据的格式固定下来。 该函数将数据打乱混合…

通俗解释hash碰撞是什么以及如何解决

Hash如何存数据 hash表的本质其实就是数组&#xff0c;hash表中通常存放的是键值对Entry。 如下图: 这里的学号是个key&#xff0c;哈希表就是根据key值来通过哈希函数计算得到一个值&#xff0c;这个值就是下标值&#xff0c;用来确定这个Entry要存放在哈希表中哪个位置。 H…

Hash碰撞

Hash碰撞 什么是Hash碰撞 Hash碰撞是指两个不同的输入值&#xff0c;经过哈希函数的处理后&#xff0c;得到相同的输出值&#xff0c;这种情况被称之为哈希碰撞。 例如&#xff1a;两个不同的对象&#xff08;object1和object2的值&#xff09;经过Hash函数计算后的&#xf…

浅谈“越权访问”

一&#xff1a;漏洞名称&#xff1a; 越权访问漏洞 描述&#xff1a; 越权访问&#xff0c;这类漏洞是指应用在检查授权&#xff08;Authorization&#xff09;时存在纰漏&#xff0c;使得攻击者在获得低权限用户帐后后&#xff0c;可以利用一些方式绕过权限检查&#xff0c;访…

逻辑越权——垂直、水平越权

水平越权&#xff1a;通过更换的某个ID之类的身份标识&#xff0c;从而使A账号获取&#xff08;修改、删除等&#xff09;B账号数据。 垂直越权&#xff1a;使用低权限身份的账号&#xff0c;发送高权限账号才能有的请求&#xff0c;获得其高权限的操作。 未授权访问&#xff1…

横向越权和纵向越权(水平越权、垂直越权)

越权&#xff1a;顾名思义&#xff0c;就是获得了本不应该有的权限。 我们都喜欢创造一些复杂的词汇&#xff0c;而实际上这些词就是一个代词&#xff0c;根本没有那么复杂。 越权漏洞往往是基于业务逻辑的漏洞&#xff0c;这样的漏洞很难被WAF保护。 越权的分类 按照方向…

越权访问

目录 概念 分类 pikachu--水平越权 源码分析 pikachu---垂直越权 源码分析 概念 越权访问&#xff08;Broken Access Control,BAC&#xff09;是web中一种常见的漏洞&#xff0c;且越权漏洞属于逻辑漏洞&#xff0c;是由于权限校验的逻辑不够严谨导致的&#xff0c;所以越…

Web 攻防之业务安全:越权访问漏洞 测试.

Web 攻防之业务安全&#xff1a;越权访问漏洞 测试. 由于没有对用户权限进行严格的判断&#xff0c;导致低权限的账号&#xff08;比如普通用户&#xff09;可以去完成高权限账号&#xff08;比如超级管理员&#xff09;范围内的操作。&#xff08;比如&#xff1a;通过更换的…

越权漏洞系列

0x01&#xff1a;越权的定义 越权漏洞是我们在测试过程中遇到比较多的漏洞&#xff0c;我们可以这样来理解越权漏洞&#xff0c;一个用户A一般只能够对自己本身的信息进行增删改查&#xff0c;然而由于后台开发人员的疏忽&#xff0c;没有在信息进行增删改查时候进行用户判断&…

java越权问题

关于java项目越权问题 问题描述实现思路具体代码 项目上线前做了安全扫描&#xff0c;安全部门扫描出一个关于越权的问题。这个问题是在刚开始开发接口的时候没有考虑到的一个事情。&#xff08;此项目是有关于用户所拥有的项目和活动权限的问题。&#xff09; 问题描述 首先…

越权 漏洞

一、越权漏洞描述 越权访问&#xff08;Broken Access Control&#xff0c;简称 BAC&#xff09;是 Web 应用程序中一种常见的漏洞&#xff0c;由于其存在范围广、危害大&#xff0c;被 OWASP 列为 Web 应用十大安全隐患的第二名。 该漏洞是指应用在检查授权时存在纰漏&#x…

详解越权漏洞

文章目录 1.1. 漏洞原理1.2. 漏洞分类1.2.1. 水平越权1.2.2. 垂直越权 1.3. 漏洞举例1.3.1. 水平越权1.3.2. 垂直越权 1.4. 漏洞危害1.5. 修复建议 1.1. 漏洞原理 越权漏洞是指应用程序未对当前用户操作的身份权限进行严格校验&#xff0c;导致用户可以操作超出自己管理权限范…