Java比较两个对象为什么要重写equals()和hashCode()

ops/2024/9/24 23:24:05/

目录

  • 1. 默认行为的局限性
  • 2. 自定义逻辑相等性
  • 3. 集合操作的正确性和性能
    • 正确性
    • 性能
  • 4. 遵循 Java 规范
    • Kotlin 中的 data class
  • 总结

在 Java 和 Kotlin 中,默认的 equals() 和 hashCode() 方法继承自 Object 类,它们的默认行为可能并不能满足你比较两个对象的需求。具体来说,重写 equals() 和 hashCode() 方法有以下几个主要原因:

1. 默认行为的局限性

equals__4">默认的 equals() 方法

默认的 equals() 方法比较的是对象的引用(内存地址),即只有当两个引用指向同一个对象时,才会返回 true。

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

hashCode__12">默认的 hashCode() 方法

默认的 hashCode() 方法返回的是对象的内存地址的哈希码,这对于对象内容的比较没有实际意义。

java">public native int hashCode();

2. 自定义逻辑相等性

在很多情况下,希望根据对象的内容(属性值)来判断两个对象是否相等,而不是它们的内存地址。例如,对于一个 Person 类,我们可能希望两个 Person 对象在姓名和年龄相等时被认为是相等的。

java">data class Person(val name: String, val age: Int) {override fun equals(other: Any?): Boolean {if (this === other) return trueif (other !is Person) return falsereturn name == other.name && age == other.age}override fun hashCode(): Int {var result = name.hashCode()result = 31 * result + agereturn result}
}

3. 集合操作的正确性和性能

在使用哈希表相关的集合(如 HashMap、HashSet 等)时,equals() 和 hashCode() 方法被用来确定对象的存储位置和比较对象是否相等。重写这两个方法可以确保这些集合的正确性和性能。

正确性

  • equals() 方法:用于比较两个对象是否相等。
  • hashCode() 方法:用于确定对象的存储桶位置。

如果两个对象根据 equals() 方法被认为是相等的,那么它们的 hashCode() 方法必须返回相同的整数结果。这是保证哈希表正确工作的关键。

性能

  • 一个良好的 hashCode() 实现可以确保对象在哈希表中的均匀分布,从而提高查找、插入和删除操作的性能。

4. 遵循 Java 规范

根据 Java 规范,equals() 和 hashCode() 方法必须满足以下条件:

  • 一致性:如果两个对象根据 equals() 方法被认为是相等的,那么它们的 hashCode() 方法必须返回相同的整数结果。
  • 对称性:如果 a.equals(b) 返回 true,那么 b.equals(a) 也必须返回 true。
  • 传递性:如果 a.equals(b) 返回 true,并且 b.equals© 返回 true,那么 a.equals© 也必须返回 true。
  • 自反性:对于任何非空引用值 x,x.equals(x) 必须返回 true。
  • 一致性:只要对象的状态没有改变,多次调用 equals() 和 hashCode() 方法应该返回相同的结果。

Kotlin 中的 data class

在 Kotlin 中,data class 自动为我们生成了 equals() 和 hashCode() 方法,基于类中所有的属性。这使得 data class 在需要比较对象内容和使用集合时非常方便。

java">data class Person(val name: String, val age: Int)

这种方式下,Kotlin 会自动生成合理的 equals() 和 hashCode() 实现,确保两个 Person 对象在属性值相等时被认为是相等的,并且具有相同的哈希码。

总结

重写 equals() 和 hashCode() 方法是为了确保对象在逻辑上相等时能够正确地进行比较和集合操作。遵循一致性、对称性、传递性、自反性和一致性的规则,能够确保这些方法的正确实现。在 Kotlin 中,使用 data class 可以自动生成这些方法,简化代码编写。


http://www.ppmy.cn/ops/93378.html

相关文章

C++11中的Lambda表达式

文章目录 C11中的Lambda表达式1.lambda表达式形式2.向lambda传递参数3.使用捕获列表4.lambda捕获和返回1.值捕获2.引用捕获3.隐式捕获4.可变lambda5.指定lambda的返回类型 C11中的Lambda表达式 1.lambda表达式形式 lambda表达式具有以下形式 [capture list] (parameter list)…

从零开始的CPP(36)——操作Excel

现有一个Excel A1.csv。 其表格第一列为:生物样本的名称;其他列为:生物样本的含量。表格第一行第一列是空格,第一行其他列为:受试者名称。 需求 如下:设计一个程序,可以指定受试者名称(某列&…

千里江山图,自动化成诗:Expect脚本详解——从入门到进阶的自动化利器

目录 引言 Expect脚本基础 什么是Expect 基本语法 进阶应用 错误处理 正则表达式 并发处理 使用Shell脚本管理多个Expect脚本 在Expect脚本内部模拟并发 脚本复用与模块化 总结 引言 在自动化运维和测试领域,Expect脚本无疑是一把强大的利器。它以其灵…

深入解析 CentOS 中的 ifcfg-eth0 配置文件

深入解析 CentOS 中的 ifcfg-eth0 配置文件 1. 引言 在 CentOS 系统中,ifcfg-eth0 是网络接口配置文件的标准命名格式,其中 eth0 表示第一个以太网接口。正确配置这些文件对确保网络连接的稳定性和可靠性至关重要。本文将详细介绍 ifcfg-eth0 文件的所…

20240813 每日AI必读资讯

Flux生成网红博主因太逼真爆火!有人用Claude写代码识破“AI美女” - Flux生成的情侣合照逼真程度达到恐怖级别,挑战人类视觉辨识能力。 - 网友发现Flux生成的照片几乎完美,但仍有细微瑕疵可供识别。 - 有人利用Flux等工具制作逼真的YouTub…

React 后台管理项目 入门项目 简洁清晰保姆级内容讲解

序章 React Hook的后台管理项目,从0到1搭建,内容非常丰富涵盖项目搭建、路由配置、用户鉴权、首页报表、用户列表、前后端联调等功能,推荐指数:5颗星! 视频学习链接: React 通用后台管理-零基础从0到1详细的入门保姆…

Springboot 实现 Modbus Rtu 协议接入物联网设备

Modbus RTU 技术教程 引言 Modbus是一种开放标准的通信协议,它最初由Modicon(现施耐德电气)在1979年发布,旨在让可编程逻辑控制器(PLC)之间能够进行通信。随着时间的发展,Modbus已经成为工业自动化领域中最常用的通信协议之一,尤其适用于连接工业电子设备。本文将详细…

Flink SQL 基础操作

Flink SQL是建立在Apache Flink之上的SQL处理引擎,它允许用户以SQL的方式处理流数据和批数据。以下是一些Flink SQL的基础操作: 一、环境准备 1.启动flink集群 ./start-cluster.sh启动sql-client ./sql-client.sh二、数据源定义 创建表(…