java之hashCode() 方法和 equals(Object obj) 方法之间的关系
1、 hashCode() 方法和 equals(Object obj)
在Java中,hashCode()
方法和 equals(Object obj)
方法之间的关系是紧密相连的,特别是在使用基于哈希的集合(如 HashSet
、HashMap
、HashTable
等)时。这两个方法共同决定了对象在哈希表中的存储和检索行为。
hashCode() 方法
hashCode()
方法用于获取对象的哈希码。- 哈希码是一个整数,由对象的内部地址或根据对象的字段通过某种算法计算得到。
- 哈希码的主要目的是在哈希表中减少碰撞(即不同的对象具有相同的哈希码)的概率,从而提高查找效率。
equals(Object obj) 方法
equals(Object obj)
方法用于比较两个对象是否相等。- 在没有重写
equals
方法的情况下,equals
方法比较的是对象的引用(即内存地址)。 - 重写
equals
方法时,通常也会重写hashCode
方法,以保持它们之间的一致性关系。
hashCode() 和 equals(Object obj) 之间的关系
- 一致性(Consistency):对于任何非null的引用值x和y,当且仅当
x.equals(y)
为true
时,x.hashCode()
必须等于y.hashCode()
。 - 不同对象可以有相同的哈希码:两个不相等的对象(即
equals(Object obj)
返回false
)可以有相同的哈希码。 - 如果两个对象相等:根据
equals(Object obj)
方法的定义,如果两个对象相等(即equals(Object obj)
返回true
),那么对这两个对象中的每一个调用hashCode()
方法都必须产生相同的整数结果。
为什么需要保持一致性
在基于哈希的集合中,当你尝试添加、查找或删除一个对象时,集合首先会计算该对象的哈希码,以决定它在哈希表中的哪个桶(bucket)中。然后,它会在该桶中遍历所有对象,使用 equals()
方法来查找确切的对象。
如果 hashCode()
方法没有与 equals()
方法保持一致,那么即使两个对象通过 equals()
方法被认为是相等的,它们也可能被放置在哈希表的不同桶中,导致无法正确找到对象,或者导致哈希表无法正确管理对象的存储和检索。
因此,当你重写 equals()
方法时,通常也需要重写 hashCode()
方法,以确保这两个方法之间的一致性。
2、不同对象可以有相同的哈希码的原因
在哈希表中,不同对象可以有相同的哈希码(也称为哈希冲突或哈希碰撞)的原因主要归结为哈希函数的有限性和对象的无限性之间的矛盾。
-
哈希函数的有限性:哈希函数的设计目标是将任意长度的输入(比如对象的状态或关键属性)映射到固定长度的输出(即哈希码,通常是整数)。由于输出空间是固定的,因此哈希函数只能产生有限数量的不同哈希码。
-
对象的无限性:在理论上,可以创建的对象数量是无限的,因为对象的属性可以有无限多种组合方式。即使只考虑有限的几个属性,这些属性的不同组合也会导致理论上无限多种不同的对象。
-
概率性:由于哈希函数的输出空间有限,而输入空间(即可能的对象集合)无限,因此必然存在多个不同的对象映射到同一个哈希码的情况。这是概率上的必然结果,尤其是在处理大量数据时。
-
性能与空间的权衡:哈希表的设计需要在性能(查找、插入和删除操作的平均时间复杂度)和空间(哈希表所需的内存)之间做出权衡。使用更复杂、输出范围更大的哈希函数可以减少哈希冲突,但会增加计算哈希码所需的时间和空间成本。相反,使用更简单、输出范围较小的哈希函数可以提高性能,但会增加哈希冲突的概率。
-
解决哈希冲突:为了处理哈希冲突,哈希表通常使用各种策略,如开放寻址法(open addressing)和链地址法(chaining,也称为分离链接法)。在链地址法中,每个桶(bucket)实际上是一个链表,所有具有相同哈希码的对象都被添加到同一个链表中。这样,即使不同对象具有相同的哈希码,它们也可以被正确地存储和检索。
因此,不同对象可以有相同的哈希码是哈希表设计中的一个固有特性,需要通过合理的哈希函数和冲突解决策略来管理。
3、介绍开放寻址法(open addressing)和链地址法(chaining,也称为分离链接法)
开放寻址法(Open Addressing)和链地址法(Chaining,也称为分离链接法)是两种解决哈希表中哈希冲突的主要方法。下面分别介绍这两种方法:
1. 开放寻址法(Open Addressing)
定义与原理:
- 开放寻址法是一种哈希表的冲突解决方法,它要求所有的元素都存储在哈希表的数组中。当发生冲突时,即两个不同的元素通过哈希函数计算得到的哈希值相同时,开放寻址法会寻找数组中的下一个空闲位置,直到找到一个空槽或遍历整个表为止。
实现方式:
- 线性探测(Linear Probing):当发生冲突时,依次检查下一个位置,直到找到一个空槽或者遍历整个表。公式为
hash(key, i) = (hash(key) + i) % tableSize
。 - 二次探测(Quadratic Probing):根据一个二次方程的形式探测下一个位置,公式为
hash(key, i) = (hash(key) + c1 * i + c2 * i^2) % tableSize
。 - 双重哈希(Double Hashing):使用两个哈希函数,第一个哈希函数计算出位置,如果发生冲突,则通过第二个哈希函数计算一个步长,再次寻找下一个位置。公式为
hash(key, i) = (hash1(key) + i * hash2(key)) % tableSize
。
优势与劣势:
- 优势:不需要额外的数据结构来存储相同哈希值的元素,节省空间。
- 劣势:可能导致聚集(clustering)问题,即相邻的位置可能会被频繁占用,导致查找效率下降。同时,扩容和重新哈希的成本较高。
2. 链地址法(Chaining,分离链接法)
定义与原理:
- 链地址法是一种通过链表解决哈希冲突的方法。在哈希表的每个槽位上,不直接存储数据元素,而是存储一个指向链表的指针。所有映射到该槽位的数据元素都存储在链表中。
实现方式:
- 当哈希函数计算出的槽位已有元素时,将新元素添加到该槽位对应链表的末尾。
- 查找、插入和删除操作都首先定位到槽位,然后在链表中进行。
优势与劣势:
- 优势:处理冲突简单,只需在链表末尾添加新元素。同时,链表的长度可以动态变化,适应不同数量的元素。
- 劣势:在极端情况下,某些槽位的链表可能非常长,导致查找效率下降。此外,链表需要额外的空间来存储指针。
装填因子:
- 在链地址法中,装填因子α定义为哈希表中关键字记录总数N与哈希表大小M的比值,即α=N/M。它反映了哈希表的填充程度,对哈希表的性能有重要影响。
综上所述,开放寻址法和链地址法各有优缺点,选择哪种方法取决于具体的应用场景和需求。
相关文章:
java之hashCode() 方法和 equals(Object obj) 方法之间的关系
1、 hashCode() 方法和 equals(Object obj) 在Java中,hashCode() 方法和 equals(Object obj) 方法之间的关系是紧密相连的,特别是在使用基于哈希的集合(如 HashSet、HashMap、HashTable 等)时。这两个方法共同决定了对象在哈希表…...
首届「中国可观测日」圆满落幕
首届中国可观测日(Observability Day)在上海圆满落幕,为监控观测领域带来了一场技术盛宴。作为技术交流的重要平台,此次活动不仅促进了观测云与亚马逊云科技之间的深化合作,更标志着双方共同推动行业发展的重要里程碑。…...
[Docker][Docker NetWork][下]详细讲解
目录 1.网络管理命令1.docker network creatre2.docker network inspect3.docker network connect4.docker network disconnect5.docker network prune6.docker network rm7.docker network ls 2.docker bridge 详解0.基本概念1.默认 bridge2.自定义 bridge3.DNS解析4.端口暴露…...
安卓系统在未来如何更好地解决隐私保护与数据安全的问题?
安卓系统可以通过以下方式更好地解决隐私保护与数据安全的问题: 强化权限控制:安卓系统可以进一步加强对应用程序权限的管理,确保用户能够清楚地知道应用程序需要哪些权限,并给予用户更多的控制权,例如允许用户选择性地…...
MySQL innodb单表上限一般多少
参考:https://www.zhihu.com/question/351797203/answer/3137174084 1.MySQL innodb单表上限为啥都说是2k万条 2.GaussDB for MySQL 为啥可以突破单表2k万的限制 要讨论这两个问题,得先明确性下实际的DB部署环境 表是索引数据是放在磁盘上的…...
更小、更安全、更透明:Google发布的Gemma推动负责任AI的进步
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
基于Django框架的医疗耗材管理系统的设计实现-计算机毕设定制-附项目源码(可白嫖)48999
摘 要 在目前的形势下,科技力量已成为我国的主要竞争力。而在科学技术领域,计算机的使用逐渐达到成熟,无论是从国家到企业再到家庭,计算机都发挥着其不可替代的作用,可以说计算机的可用领域遍及生活、工作的各个方面。…...
物联网协议篇(1):modbus tcp和modbusRTU的区别是什么?
Modbus TCP和Modbus RTU是Modbus协议中的两种主要变体,它们在多个方面存在显著的区别。以下是它们之间的主要区别: 1. 物理层和数据传输方式 Modbus TCP (TCP/IP): 使用以太网作为物理层,通过TCP/IP协议进行通信。数据以数据包的形式在TCP连接上传输,具有较高的通信速度和…...
JVM系列 | 对象的消亡——HotSpot的设计细节
HotSpot 的细节实现 文章目录 HotSpot 的细节实现OopMap 与 根节点枚举根节点类型及说明HotSpot中的实现 OopMap 与 安全点安全点介绍如何保证程序在安全点上? 安全区域记忆集与卡表记忆集卡表 写屏障并发的可达性分析(与用户线程)并发可达性…...
vue 运行或打包过程报错 JavaScript heap out of memory(内存溢出)
安装 increase-memory-limit npm install increase-memory-limit 运行increase-memory-limit ./node_modules/.bin/increase-memory-limit 运行后会报以下错误: "node --max-old-space-size10240" 不是内部或外部命令,也不是可运行的程序…...
git分支提交方法
先下载最新代码 改动文件覆盖 cp 文件到~/file/ git add添加文件 git commit提交本地 建立分支 git diff .c git status -uno git add git commit git checkout -b issue-lyd git push origin issue-lyd...
从微架构到向量化--CPU性能优化指北
引入 定位程序性能问题,相信大家都有很多很好的办法,比如用top/uptime观察负载和CPU使用率,用dstat/iostat观察io情况,ptrace/meminfo/vmstat观察内存、上下文切换和软硬中断等等,但是如果具体到CPU问题,我…...
声声入耳,事事如意 爱可声「如意」助听器即将上市!
如意助听器 Charm 爱可声全新系列「如意」助听器即将上市! 此次新品充分考虑了不同听损以及年龄的用户需求, 融合三大强劲性能。 1、多群体覆盖,定制个性化方案 如意助听器针对不同听损程度的听障患者设计了不同款式助听器,贴…...
生物实验室设备文件采集如何才能质量和效率双管齐下?
生物实验室的设备文件采集是实验室运营、科研活动和数据科学实践应用中不可或缺的一环。通过数据采集,实验室可以优化资源配置、提高实验结果的准确性和可靠性、支持科研水平的提升,并确保数据的安全性和可追溯性。因此,实验室应高度重视设备…...
Framework源码整编、单编、烧录过程
目录 一.背景 二.整编方式 二.单编方式 三.烧录 一.背景 源码编译分为整编和单编,整编通常耗时较长,单编则速度很多,如果我们进行一个小的修改想要立马验证的话单编就很合适 二.整编方式 开始执行编译操作,总共三步. 执行source操作source build/envsetup.sh .执行lunc…...
TypeScript类型断言
TypeScript类型断言是TypeScript中一个强大且有用的特性,它允许开发者在编译时明确指定一个值的类型,即使TypeScript无法自动推断出这个类型。类型断言类似于其他编程语言中的类型转换,但它不会改变变量的运行时值,而只是告诉编译…...
Mallet:一款针对任意协议的安全拦截代理工具
关于Mallet Mallet是一款功能强大的协议安全分析工具,该工具支持针对任意协议创建用于安全审计的拦截代理,该工具本质上与我们所熟悉的拦截Web代理类似,只是通用性更强。 工具运行机制 Mallet建立在Netty框架之上,并且依赖于Net…...
【IEEE出版】第五届大数据、人工智能与软件工程国际研讨会(ICBASE 2024,9月20-22)
第五届大数据、人工智能与软件工程国际研讨会(ICBASE 2024)将于2024年09月20-22日在中国温州隆重举行。 会议主要围绕大数据、人工智能与软件工程等研究领域展开讨论。会议旨在为从事大数据、人工智能与软件工程研究的专家学者、工程技术人员、技术研发人…...
自修室预约小程序的设计
管理员账户功能包括:系统首页,个人中心,学生管理,公告通知管理,自修室管理,座位预约管理,预约取消管理,管理员管理,系统管理 微信端账号功能包括:系统首页&a…...
用于跟踪个人图书馆的BookLogr
什么是 BookLogr ? BookLogr 是一款网络应用,旨在帮助您轻松管理个人图书馆。这项自托管服务可确保您完全控制数据,提供安全且私密的方式来跟踪您拥有、阅读或希望阅读的所有书籍。您也可以选择向公众自豪地展示您的图书馆,与您的…...
深入解析JVM垃圾回收机制:Full GC、Minor GC与Major GC
目录 引言垃圾回收的基本概念 什么是垃圾回收GC的分类JVM内存模型 堆内存非堆内存Minor GC 触发条件运行机制对性能的影响...
Windows10点击文件夹右键卡死的解决办法
1、首先同时按下【WinR】打开运行页面,输入命令【regedit】按下回车或者点击确定。 2、打开注册表编辑器后,定位到如下位置“HKEY_CLASSES_ROOT\Directory\Background\Shellex\ContextMenuHandlers”。 3、然后在其中将所有名为“New”的文件或项全部删…...
C# 设计模式之单例模式
总目录 前言 本文是个人基于C#学习设计模式总结的学习笔记,希望对你有用! 1 基本介绍 定义:确保一个类只有一个实例,并提供一个全局访问点。 本质就是保证在整个应用程序的生命周期中,任何一个时刻,单例…...
【组合数学】【Python】【小练习】一、斯特灵近似式求阶乘
一、问题介绍 斯特灵(Stirling)近似式,是数学分析中,用于求阶乘近似值的一个常用公式,其简单的表述形式为: 二、Python实现 使用Python,循环从n1至n98,分别输出n的阶乘值、斯特灵公…...
【IEEE Fellow特邀报告,JPCS独立出版】第四届电子通信与计算机科学技术国际学术会议(ECCST 2024,9月20-22)
2024年第四届电子通信与计算机科学技术国际学术会议将于2024年9月20-22日在中国上海举行。 会议旨在为从电子与通信、网络、人工智能与计算机技术研究的专家学者、工程技术人员、技术研发人员提供一个共享科研成果和前沿技术,了解学术发展趋势,拓宽研究思…...
DockerCompose部署示例
目录 前言 1. 初识DockerCompose 2. 安装DockerCompose 3. 部署微服务项目 1)找一个目录,创建一个新的cloud-demo文件夹。 2)在cloud-demo文件夹创建一个docker-compose.yml文件,然后编写下面内容: 3)…...
【云原生】Helm来管理Kubernetes集群的详细使用方法与综合应用实战
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...
电源插头应该统一方向
大家在使用插排的时候就会发现,有的横向,有的竖向。 国家强制规定,统一方向,插排能方便使用。...
大学新生编程入门最佳攻略
引言 编程的重要性:简述编程在当今社会的地位,为何它是大学生的必备技能。目标设定:明确文章旨在帮助新生从零基础开始,逐步成长为编程高手。 方向一:编程语言选择 1. 编程语言概览 介绍几种流行语言:如…...
MySQL 的binlog 、undolog 、redolog
Binlog (二进制日志) bin Log 作用 用于记录所有修改数据库数据的 SQL 语句或行级别的变化,主要用于主从复制和数据恢复。 binlog格式 STATEMENT模式:binlog里面记录的就是SQL语句的原文。优点是并不需要记录每一行的数据变化,减少了binlo…...
织梦网站搜索怎么做/网站推广的方法和途径
很有可能是地图投影的问题...
做网站编码/seo推广技术
1, Java的基本部分 1.1 java中int数据占几个字节 1.2 有了基本类型, 为什么还需要包装类型? 1.3 说一下""和equals方法的区别? 1.4 讲一下String和StringBuilder的区别(final)?StringBuffer和StringBuilder的区别? 1.5, 讲一下java中的集合? 1.6 Ar…...
wordpress 网店 主题/打开百度网页版
打比方一个类里边有多个内部类,怎样获取该类里边指定的某一个内部类public class FactoryTest {Testpublic void test2(){FactoryTest factoryTest new FactoryTest();Class extends FactoryTest> clazz factoryTest.getClass();Class>[] classes clazz.ge…...
mip网站案例/做推广网络
1、行列式的本质是线性变换的放大率,而矩阵的本质就是个数表。 2、行列式行数列数,矩阵不一定(行数列数都等于n的叫n阶方阵),二者的表示方式亦有区别。 3、行列式与矩阵的运算明显不同 (1) 相…...
哪个网站专业做安防/百度极速版推广
爬虫项目介绍 有一定的复杂性可以灵活调整项目的复杂性平衡语言/爬虫之间的比重通用爬虫,如baidu,google聚焦爬虫,从互联网获取结构化数据 把网页转换成数据 go语言的爬虫库/框架 henrylee2cn/pholcusgocrawlcollyhu17889/go_spider 不使用现成爬虫库/框架来写一个…...
阳江网签/百度seo如何优化
前面简单地了解了一下IdleStateHandler,我们现在写一个简单的心跳demo: 1)服务器端每隔5秒检测服务器端的读超时,如果5秒没有接受到客户端的写请求,也就说服务器端5秒没有收到读事件,则视为一次超时 2&…...