Hash与HashCode

article/2025/9/30 4:20:45

1.hash和hash表

首先看一张来自百度百科的解释

在这里插入图片描述
在这里插入图片描述
  hash是一个函数,该函数中的实现就是一种算法,就是通过一系列的算法来得到一个hash值,hash表就是所有的hash值组成的,有很多种hash函数,也就代表着有很多种算法得到hash值。

2.hashCode

  hashcode就是通过hash函数得来的,通俗的说,就是通过某一种算法得到的,hashcode就是在hash表中有对应的位置。

  每个对象都有hashcode,对象的hashcode怎么得来的呢?

  首先一个对象肯定有物理地址,hashcode代表对象的地址是对象在hash表中的位置,物理地址说的对象存放在内存中的地址,通过对象的内部地址(也就是物理地址)转换成一个整数,然后该整数通过hash函数的算法就得到了hashcode。

  举个例子,hash表中有 hashcode为1、hashcode为2、(…)3、4、5、6、7、8这样八个位置,有一个对象A,A的物理地址转换为一个整数17(这是假如),就通过直接取余算法,17%8=1,那么A的hashcode就为1,且A就在hash表中1的位置。

3.hashCode的作用

  HashCode的存在主要是为了查找的快捷性,HashCode是用来在散列存储结构中确定对象的存储地址的(后半句说的用hashcode来代表对象就是在hash表中的位置)。

  为什么hashcode就查找的更快?

  比如:我们有一个能存放1000个数这样大的内存中,在其中要存放1000个不一样的数字,用最笨的方法,就是存一个数字,就遍历一遍,看有没有相同得数,当存了900个数字,开始存901个数字的时候,就需要跟900个数字进行对比,这样就很麻烦,很是消耗时间,用hashcode来记录对象的位置,来看一下。hash表中有1、2、3、4、5、6、7、8个位置,存第一个数,hashcode为1,该数就放在hash表中1的位置,存到100个数字,hash表中8个位置会有很多数字了,1中可能有20个数字,存101个数字时,他先查hashcode值对应的位置,假设为1,那么就有20个数字和他的hashcode相同,他只需要跟这20个数字相比较(equals),如果每一个相同,那么就放在1这个位置,这样比较的次数就少了很多,实际上hash表中有很多位置,这里只是举例只有8个,所以比较的次数会让你觉得也挺多的,实际上,如果hash表很大,那么比较的次数就很少很少了。

4.equals和hashcode

  首先我们要知道hsahCode规则:

  1. 如果两个对象equals相等,那么这两个对象的HashCode一定也相同
  2. 如果两个对象的HashCode相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,存放于同一个位置

  equals() 的作用是 用来判断两个对象是否相等。

  equals() 定义在JDK的Object.java中。通过判断两个对象的地址是否相等(即,是否是同一个对象)来区分它们是否相等。源码如下:

public boolean equals(Object obj) {return (this == obj);
}

  由源码可以看出,使用默认的“equals()”方法,等价于“==”方法。因此,我们通常会重写equals()方法:若两个对象的内容相等,则equals()方法返回true;否则,返回fasle。

  下面根据“类是否覆盖equals()方法”,将它分为2类。

  1. 若某个类没有覆盖equals()方法,当它的通过equals()比较两个对象时,实际上是比较两个对象是不是同一个对象。这时,等价于通过“==”去比较这两个对象。
  2. 我们可以覆盖类的equals()方法,来让equals()通过其它方式比较两个对象是否相等。通常的做法是:若两个对象的内容相等,则equals()方法返回true;否则,返回fasle。

  以String为例,假设我们String s1 = new String("123");String s2 = new String("123");s1==s2就会返回false,s1.equals(s2)就会返回true。

  如果一个类重写了equals(),也必须重写hashCode(),否则equals()无效。即equals()返回true,hashCode()值也不一定一样。该类的“hashCode() 和 equals() ”没有半毛钱关系的!这种情况下,equals() 用来比较该类的两个对象是否相等。而hashCode() 则根本没有任何作用。

  还以上面的例子为例,假如只重写equals而不重写hashcode,那么String类的hashcode方法就是Object默认的hashcode方法,由于默认的hashcode方法是根据对象的内存地址经哈希算法得来的,显然此时s1!=s2,故两者的hashcode不一定相等。

  然而重写了equals,且s1.equals(s2)返回true,还记得上面的规则吗,两个对象相等其哈希值一定相等,所以矛盾就产生了,因此重写equals一定要重写hashcode,而且从String类重写后的hashcode方法中可以看出,重写后返回的新的哈希值与String的值有关。

5.hsah冲突的解决办法

  我们知道,对象Hash的前提是实现equals()和hashCode()两个方法,那么HashCode()的作用就是保证对象返回唯一hash值,但当两个对象计算值一样时,这就发生了碰撞冲突。如下将介绍如何处理冲突,当然其前提是一致性hash。

5.1 开放地址法

  开放地执法有一个公式:Hi=(H(key)+di) MOD m i=1,2,…,k(k<=m-1)

  其中,m为哈希表的表长。di 是产生冲突的时候的增量序列。如果di值可能为1,2,3,…m-1,称线性探测再散列。

  如果di取1,则每次冲突之后,向后移动1个位置.如果di取值可能为1,-1,4,-4,9,-9,16,-16,…kk,-kk(k<=m/2),称二次探测再散列。
  如果di取值可能为伪随机数列。称伪随机探测再散列。
在这里插入图片描述

  线性探测再散列,依次往表里存数据,如果算出来的地址上已经有人了,那就往后挪一个位置,如果还有人就再挪一个,直到找到位置。
  二次探测再散列,与线性探测再散列类似,只是每次挪的位置为1,-1,4,-4……

5.2 链地址法(拉链法)

  将所有hash地址相同的记录都链接到同一链表中。

  HashMap就是这么实现的。

在这里插入图片描述
  与开放定址法相比,拉链法有如下几个优点:

  1. 拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;
  2. 由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;
  3. 开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;
  4. 在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。

拉链法的缺点:

  指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间,而若将节省的指针空间用来扩大散列表的规模,可使装填因子变小,这又减少了开放定址法中的冲突,从而提高平均查找速度。

5.3 再哈希法

  再哈希法是指第一次散列产生哈希地址冲突,为了解决冲突,采用另外的散列函数或者对冲突结果进行处理的方法。

5.4建立一个公共溢出区

  假设哈希函数的值域为[0,m-1],则设向量HashTable[0…m-1]为基本表,另外设立存储空间向量OverTable[0…v]用以存储发生冲突的记录。
也就是建立一个公共溢出区域,就是把冲突的都放在另一个地方,不在表里面。






本文的一切图片皆来源于网络,如有侵权,请及时联系我


http://chatgpt.dhexx.cn/article/fn1t5PkM.shtml

相关文章

深入理解 Java 中的 hashCode

深入理解 Java 中的 hashCode 一、hashCode 方法二、为什么重写 equals 方法的时候必须重写 hashCode 方法&#xff1f; 一、hashCode 方法 Java 是一门面向对象的编程语言&#xff0c;所有的类都会默认继承自 Object 类&#xff0c;Object 类中就包含了 hashCode() 方法&…

hashCode 和对象的内存地址

hashCode 文章目录 hashCodehashCode 的生成逻辑第 0 种算法第 1 种算法第 2 种算法第 3 种算法第 4 种算法第 5 种算法 根据一定的规则将与对象相关的信息&#xff08;比如对象的存储地址&#xff0c;对象的字段等&#xff09;映射成一个数值&#xff0c;这个数值称作为散列值…

HashCode

HashCode 文章目录 HashCode前言Hash是什么&#xff1f;HashCodeHashCode关键点判断两个对象相等 前言 Hash是什么&#xff1f; 哈希函数 把任意长度的输入通过散列算法变换成固定长度的输出&#xff0c;该输出就是散列值&#xff0c;是一种压缩映射。 hash是一个函数&#…

java中equals,hashcode和==的区别

2019独角兽企业重金招聘Python工程师标准>>> 1、== java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型 byte,short,char,int,long,float,double,boolean 他们之间的比较,应用双等号(==),比较的是他们的值。 2.引用类型(类、接口、数组) 当…

hashcode讲解【最详细版本】

Object 基类 Object 含有的方法 hashCode 作用&#xff1a;用于查找的快捷性&#xff0c;常用于确定对象的存储地址 如 Hashtable&#xff0c;HashMap 默认情况下&#xff0c;Object中的hashCode() 返回对象的32位jvm内存地址。 如果两个对象相同&#xff0c; equals方法一…

hashcode详解

前言 HashCode是在Java中用于获取对象的唯一标识符的方法。它是根据对象的内容生成的一个整数值。对象的hashCode()方法被调用时&#xff0c;它返回的是对象的哈希码。哈希码可以用于在哈希表等数据结构中快速定位对象。 在Java中&#xff0c;hashCode()方法是被Object类定义…

真正搞懂hashCode和hash算法

本人当初刚接触java的时候一说到hash算法或者hashCode也是蛋蛋疼&#xff0c;两只都疼 后来花了整整一天时间来研究hash&#xff0c;搞懂后发现其实也不难理解&#xff0c;时隔一年突然想起来&#xff0c;写篇博客记录下&#xff1b; 以前我莫得选择&#xff0c;现在我想搞懂…

腾讯_TEG一面

总结 不愧是腾讯内部技术含量较高的部门&#xff0c;上来怼基础。总体有套路可循&#xff0c;比较偏技术

腾讯技术解读|TEG—硬核拆解,腾讯产品的底层技术牛在哪里?

技术&#xff0c;是各个事业群的核心力量 然而&#xff0c;事业群的不同&#xff0c;核心力量也不同 你是否还在纠结事业群的选择&#xff1f; 担心对事业群不了解而选错事业群&#xff1f; 毫无疑问 技术也是事业群选择的重要衡量因素之一哦&#xff01; 对此&#xff0c…

15 年腾讯老兵谈技术人成长之路

作者&#xff1a;alexguo&#xff0c;腾讯TEG技术总监&技术专家 每个职场人都会经历从职场新人到骨干、专家亦或是管理者的蜕变过程。作为技术职业人&#xff0c;大家常会碰到一些困惑&#xff0c;在不同职业发展阶段所需要具备的认知和专业能力差异在哪里&#xff1f;除了…

腾讯TEG客户端开发面经

2022年秋招/春招/提前批/大厂面经整理&#xff08;持续更新中~&#xff09; 腾讯TEG客户端开发面经 2021/05/19下午两点半初试 1、面试官先让做自我介绍&#xff0c;主要介绍项目&#xff0c;简短一点不需要太详细。 ------我大概讲了一下我的三个项目&#xff0c;第一个是高…

腾讯TEG首次集体亮相腾讯全球数字生态大会,这些亮点不容错过!

5月21日—23日&#xff0c;腾讯全球数字生态大会将在昆明滇池国际会展中心召开。大会是将腾讯过往的三大峰会“腾讯全球合作伙伴大会”、“腾讯云未来峰会”和“互联网数字经济峰会”进行有机整合&#xff0c;届时&#xff0c;众多行业领袖、技术领军人物、国际知名数字经济研究…

粉丝投稿!大三参加校招三面腾讯TEG实习岗面经分享,希望对大家有帮助!(已拿意向书)

背景介绍 背景&#xff1a;本科大三&#xff0c;末流211&#xff0c;计科专业&#xff0c;寒假在某bat一家实习 腾讯流程好快&#xff0c;从面到结束一周拿意向书&#xff0c;3.18开始一面&#xff0c;3.25拿到意向书 一面 75min 自我介绍学校做的项目有没有什么优点&#x…

TEG《选择》乘风破浪 · 披荆斩棘

等灯等灯&#xff5e; 今夜&#xff0c;TEG《选择》在新年晚会闪亮登场 听说有人夸我们大歌舞大排面&#xff08;蟹蟹&#xff09; 其实咱剧情还搭载着回忆与梦境、理想与现实 来&#xff0c;他二哥就好好跟大家唠嗑唠嗑这《选择》 选择音乐剧 几句话概括我们的故事主线&#x…

什么是IEGT?

1980年前后&#xff0c;通用公司的B•贾扬•巴利加发明了IGBT&#xff0c;解决了当时MOSFET和普通双极功率晶体管无法解决的问题。但随着产品的发展&#xff0c;大家发现了这种新型器件拥有静态损耗的问题。于是东芝半导体的工程师就在上个世纪九十年代率先实现了栅极注入增强&…

关于【腾讯 TEG云架构平台部( 云架平) 存储组】

这算是个简单的辟谣帖吧 本人21届新人&#xff0c;入职快半年了&#xff0c;之前也在这边实习过半年&#xff0c;几乎不怎么看脉脉&#xff0c;但最近看到一些黑帖&#xff0c;本不想回复&#xff0c;但是考虑到自己也是应届生过来的&#xff0c;刚拿到offer肯定忍不住想从各方…

Carla自动驾驶仿真三:Traffic Manager交通管理器详解

CARLA Traffic Manager 一、什么是Traffic Manager1、Traffic Manager简介2、Traffic Manager框架3、Traffic Manager模块 二、Traffic Manager控制方法1、TM控制交通参与者的自动驾驶的规则2、TM控制交通参与者行为的API摘要3、TM控制交通参与者行为的API 三、Traffic Manager…

[carla入门教程]-5 使用ROS与carla通信

本专栏教程将记录从安装carla到调用carla的pythonAPI进行车辆操控并采集数据的全流程,带领大家从安装carla开始,到最终能够熟练使用carla仿真环境进行传感器数据采集和车辆控制. 第五节 使用ros与carla通信 本小节的主要内容是介绍carla中的如何使用ros进行通信. 章节内容介…

CARLA安装记录(二)

安装好显卡驱动后&#xff0c;接下来的步骤是安装Unreal Engine。我的操作系统是Ubuntu 18.04 系统要求 Ubuntu 18.04。CARLA兼容Ubuntu 16.04及之前版本&#xff0c;但虚幻引擎正常工作需要合适的编译器。至少130GB磁盘空间。CARLA会占用大约31GB的空间&#xff0c;而虚幻引…

Carla安装记录

Carla安装记录 最近打算在做一些自动驾驶相关的东西&#xff0c;所以安装了一下Carla。在这里记录一些自己的安装过程中遇到的一些问题和解决的方法。 Carla release版本下载 想要安装Carla&#xff0c;可以选择release版本或者源码安装。在这里我主要介绍release版本的安装…