Object.hashCode() 详解

在Java编程中,hashCode方法是一个常见而重要的概念。它通常用于哈希表、集合以及一些需要高效检索数据的数据结构中。然而,对于许多开发者来说,hashCode方法可能是一个容易被忽略或者被简单实现的部分。在本文中,我们将深入探讨Java中hashCode的一些思考,以便更好地理解其背后的原理和影响。

hashcode.jpg

hashCode的简介

hashCode 返回的 “散列码” 是指通过哈希算法生成的一个整数,用于标识对象的唯一性。在Java中,hashCode方法被设计用来支持基于哈希的集合类,如HashMap、HashSet等,以及其他需要快速检索数据的数据结构。

hashCode的意义

  • 快速检索

散列码的主要作用是提高数据结构的检索效率。在哈希表中,通过散列码可以迅速定位到存储数据的位置,而不需要遍历整个数据集。这对于大规模数据集的快速检索非常重要,能够使得检索操作的时间复杂度接近常数级别。

  • 哈希集合性能

在使用哈希集合(如HashSet)时,散列码决定了元素在集合中的存储位置。如果不同的对象具有相同的散列码,就会发生哈希冲突,需要通过其他手段解决,如链地址法或开放寻址法。因此,好的散列码设计能够最小化哈希冲突,提高哈希集合的性能。

  • equals方法辅助

hashCode方法与equals方法是相关联的。在Java中,根据对象相等性的定义,如果两个对象相等(equals方法返回true),那么它们的散列码应该相等。这一关系有助于在哈希集合中正确地比较和存储对象。

  • 分布均匀

散列码的设计应尽量使得不同的对象生成不同的散列码,以减少哈希冲突的可能性。这需要考虑到对象的各个属性,确保它们都对最终的散列码有贡献,避免简单地依赖于某一个属性。

重写 hashCode 方法

为什么要重写 hashCode 方法

Object类中提供的默认实现是与当前线程有关的随机数和其他三个固定值进行xorshift运算后的结果数。这种默认实现在实际应用中可能并不总是满足需要,特别是当我们需要基于对象的内容来计算哈希码时。

源码如下:

public native int hashCode();

如何重写hashCode方法

在自定义类中,如果希望基于对象的内容生成哈希码,通常需要重写hashCode()方法。为了简化哈希码的计算,我们可以使用Objects工具类,提供了hash方法,可以接受多个参数,并根据它们生成一个合并后的哈希码。

示例如下:

@Data
public class UrlEntity {private Integer id;private String url;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;UrlEntity entity = (UrlEntity) o;return Objects.equals(id, entity.id) && Objects.equals(url, entity.url);}@Overridepublic int hashCode() {return Objects.hash(id, url);}

哈希冲突

由于哈希码是一个有限位数的整数,不同的对象可能生成相同的哈希码,这就是哈希冲突。为了最小化哈希冲突的概率,好的哈希码应该能够均匀分布。在实际应用中,可以通过一些技巧和算法来提高哈希码的质量,减少冲突的可能性。

比如如下代码:

public static void main(String[] args) {String str1 = "3C";String str2 = "2b";System.out.println("字符串"+str1+"的hashCode值为:"+str1.hashCode());System.out.println("字符串"+str2+"的hashCode值为:"+str2.hashCode());
}

运行结果为:

字符串3C的hashCode值为:1648
字符串2b的hashCode值为:1648

不同的对象,却拥有了相同的 hashCode值, 这就是哈希冲突。

为什么重写equals方法时一定要重写hashCode方法

在Java中,equals 方法和 hashCode 方法之间存在一种协定,这个协定规定了如果两个对象根据 equals 方法被认为相等,那么它们的 hashCode 值必须相等。反之亦然,如果两个对象的 hashCode 值相等,它们不一定要相等。

这一规定的原因在于,在使用基于散列的集合类(例如 HashMap、HashSet 等)时,对象的 hashCode 值通常用于确定对象在内部存储结构中的位置。当你在集合中使用对象时,集合会首先检查对象的 hashCode 值,然后再使用 equals 方法来确保这个位置上没有相等的对象。

如果你重写了 equals 方法但没有重写 hashCode 方法,那么可能会导致违反这个协定,即相等的对象具有不同的 hashCode 值。这样的情况会导致在使用散列集合时出现问题,因为相等的对象应该被视为相等,它们应该在集合中占据相同的位置。

总结

在Java中,Object.hashCode()方法在处理集合类和对象比较时发挥着关键作用。了解其原理以及如何正确重写这个方法对于编写高效、正确的代码至关重要。通过理解哈希码的生成方式,我们可以更好地利用Java的集合类,并确保我们的自定义类在使用这些类时能够正确地工作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/299925.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ElasticSearch 使用映射定义索引结构

动态映射 dynamic 可选值解释true默认值,启用动态映射,新增的字段会添加到映射中runtime查询时动态添加到映射中false禁用动态映射,忽略未知字段strict发现未知字段,抛出异常 显示映射 创建映射 PUT user {"mappings&qu…

VMware安装linux系统一

1、创建虚拟机 1.1、创建新的虚拟机 1.2、进入安装向导 1.3、安装操作系统,选择稍后安装操作系统 1.4、选择Linux,版本选择CentOS64位 1.5、设置虚拟机名称和安装位置 1.6、设置磁盘大小 1.7、创建虚拟机 1.8、完成安装 2、配置虚拟机 2.1、选择编辑虚拟机 2.2、修…

假期返乡的消费者,县城外卖消费上涨,如何实现外卖自由?

假期即将来临,年轻的消费者回到小县城过节,也开始将他们的"外卖买一切"的消费习惯带回了家乡。线上"赶集"的新型消费模式让消费者在家门口一站式购齐年货,既方便又实惠。因此,小县城的外卖订单量也大幅增长。…

Jenkins的特殊操作定时自动执行任务以及测试报告调优

java -Dhudson.model.DirectoryBrowserSupport.CSP -jar Jenkins.war 测试报告 不美丽 执行上面的代码 重启jenkins 就好了

浅谈故障注入目的与优势

故障注入是一种有意识地向系统或软件中引入错误、故障或异常的测试技术。这种方法旨在评估系统在异常情况下的表现,并帮助发现潜在的问题,以便在生产环境中减少故障的风险。本文将介绍故障注入目的与优势有哪些! 故障注入的主要目的是在安全的环境下评估…

关于Dark Frost 僵尸网络对游戏行业进行DDoS攻击的动态情报

一、基本内容 近期,一种名为Dark Frost 的新型僵尸网络被发现正在对游戏行业发起分布式拒绝服务攻击(DDoS)。目标包括游戏公司、游戏服务器托管提供商、在线流媒体甚至和网络信息安全攻击者直接交互的其他游戏社区成员。截至2023年2月,僵尸网…

sqlilabs第三十二三十三关

Less-32(GET - Bypass custom filter adding slashes to dangerous chars) 手工注入 由 宽字符注入可知payload 成功触发报错 http://192.168.21.149/Less-32/ ?id1%df 要写字符串的话直接吧字符串变成ascii码 注意16进制的表示方式 自动注入 sqlmap -u http:…

修改PCIE 设备控制寄存器DevCtl2参数

如何修改PCIE 设备控制寄存器DevCtl2参数? 参考书籍:PCI_Express_Base_Spec 如图所示:输入Lspci -s 00:08:00 -vvv|grep - i deve 输出DevCap、DevCtl、DevCap2、DevCtl2参数,本节重点分析UEFI BIOS怎么设置…

【基础篇】一、认识JVM

文章目录 1、虚拟机2、Java虚拟机3、JVM的整体结构4、Java代码的执行流程5、JVM的三大功能6、JVM的分类7、JVM的生命周期 1、虚拟机 虚拟机,Virtual Machine,一台虚拟的计算机,用来执行虚拟计算机指令。分为: 系统虚拟机&#x…

《PySpark大数据分析实战》-19.NumPy介绍ndarray介绍

📋 博主简介 💖 作者简介:大家好,我是wux_labs。😜 热衷于各种主流技术,热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员(PCTA)、TiDB数据库专家(PCTP…

.net6使用Sejil可视化日志

(关注博主后,在“粉丝专栏”,可免费阅读此文) 之前介绍了这篇.net 5使用LogDashboard_.net 5logdashboard rootpath-CSDN博客 这篇文章将会更加的简单,最终的效果都是可视化日志。 在程序非常庞大的时候&…

时间Date

你有没有思考过时间问题: 前端为什么可以直接看见时间格式的数据 后端怎么接受的数据,怎么处理的 一般来说:前端传输来数据都是时间格式的字符串,那么后端需要能够解析时间格式的字符串,归功于JSONFormat ,可以解析…