当前位置: 首页 > news >正文

重写 `equals` 和 `hashCode` 的一致性

重写 equalshashCode 的一致性

在 Java 中,当我们重写 equals 方法时,通常需要同时重写 hashCode 方法,以确保对象在逻辑上相等时,其哈希值也相等。这是一种重要的契约(contract),主要用于集合框架和哈希相关操作。


equalshashCode 的规则

  1. equals 方法

    • 用于比较两个对象是否 “逻辑上相等”。
    • 默认实现是比较内存地址,重写后可以定义自己的相等规则(例如根据属性值)。
  2. hashCode 方法

    • 用于生成对象的哈希码,是一个整数值。
    • 默认实现与内存地址相关,重写后需根据对象的逻辑属性生成哈希码。

为什么需要同时重写?

  • 在集合框架(如 HashSetHashMap 等)中,对象的存储和检索通常依赖 hashCodeequals 的协作。
  • 如果只重写了 equals,而未重写 hashCode,会导致逻辑相等的对象在集合中无法正常工作。

规则

  • 如果两个对象根据 equals 方法相等,那么它们的 hashCode 值必须相等。
  • 如果两个对象的 hashCode 值相等,equals 方法不一定返回 true

具体案例分析

只重写 equals 方法的情况

代码

class Person {String name;Person(String name) {this.name = name;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return name.equals(person.name);}
}public class Main {public static void main(String[] args) {Person p1 = new Person("Alice");Person p2 = new Person("Alice");HashSet<Person> set = new HashSet<>();set.add(p1);System.out.println(set.contains(p2));  // 输出 false}
}

问题

  • p1.equals(p2) 返回 true,逻辑上它们相等。
  • 但是,由于未重写 hashCodep1p2 的哈希值不同,因此集合认为它们是不同的对象,contains 方法返回 false

同时重写 equalshashCode

代码

import java.util.Objects;class Person {String name;Person(String name) {this.name = name;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return name.equals(person.name);}@Overridepublic int hashCode() {return Objects.hash(name);}
}public class Main {public static void main(String[] args) {Person p1 = new Person("Alice");Person p2 = new Person("Alice");HashSet<Person> set = new HashSet<>();set.add(p1);System.out.println(set.contains(p2));  // 输出 true}
}

解决了什么问题

  • 逻辑上相等的 p1p2 返回相同的哈希值,因此 HashSet 可以正常处理它们。

equalshashCode 的工作流程

以下是哈希集合(如 HashMapHashSet)的操作流程:

  1. 存储对象

    • 根据对象的 hashCode 值确定存储位置(桶)。
    • 如果桶中已有元素,则使用 equals 方法检查是否重复。
  2. 检索对象

    • 通过 hashCode 定位对象所在的桶。
    • 在桶中使用 equals 方法逐一比较找到匹配的对象。

注意

  • 如果 hashCode 返回不一致的值,可能导致对象存储和检索失败。
  • 如果 equals 不一致,则可能导致重复存储或检索错误。

hashCode 的实现建议

  1. 一致性:对象属性未改变时,hashCode 的值必须保持不变。
  2. 关联性:如果 equals 返回 truehashCode 值必须相等。
  3. 性能:尽量避免生成大量冲突的哈希值,分布应均匀。

推荐实现

  • 使用 Objects.hash 或 IDE 自动生成代码。

总结

  1. equalshashCode 的一致性是 Java 集合框架正常运行的基础
  2. equals 用于定义逻辑相等性,hashCode 用于哈希结构的性能优化
  3. 同时重写两者可以避免逻辑错误,确保对象在哈希集合中的正确行为

相关文章:

重写 `equals` 和 `hashCode` 的一致性

重写 equals 和 hashCode 的一致性 在 Java 中&#xff0c;当我们重写 equals 方法时&#xff0c;通常需要同时重写 hashCode 方法&#xff0c;以确保对象在逻辑上相等时&#xff0c;其哈希值也相等。这是一种重要的契约&#xff08;contract&#xff09;&#xff0c;主要用于…...

【游戏设计原理】14 - MDA:游戏的机制、运行和体验

1. 学习、分析并总结 MDA 原理 MDA (Mechanics, Dynamics, and Aesthetics) 是一种用来分析和理解游戏设计的框架&#xff0c;由 Marc LeBlanc, Robin Hunicke, 和 Robert Zubek 提出。这个框架将游戏分解为三个核心要素&#xff1a; Mechanics&#xff08;机制&#xff09;&…...

鸿蒙Next创建自定义组件总结

一、引言 在鸿蒙Next开发中&#xff0c;自定义组件是构建高效、可维护UI的重要组成部分。它具有可组合、可重用以及数据驱动UI更新等特点&#xff0c;能帮助开发者更好地实现代码复用、业务逻辑与UI分离等目标。本文将详细总结创建自定义组件的相关知识&#xff0c;包括其基本…...

redis 缓存使用

工具类 package org.springblade.questionnaire.redis;import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factor…...

Javascript面试手撕常见题目(回顾一)

1.JS查找文章中出现频率最高的单词? 要在JavaScript中查找文章中出现频率最高的单词&#xff0c;你可以按照以下步骤进行操作&#xff1a; 将文章转换为小写&#xff1a;这可以确保单词的比较是大小写不敏感的。移除标点符号&#xff1a;标点符号会干扰单词的计数。将文章拆…...

lc146LRU缓存——模仿LinkedHashMap

146. LRU 缓存 - 力扣&#xff08;LeetCode&#xff09; 法1&#xff1a; 调用java现有的LinkedHashMap的方法&#xff0c;但不太理解反正都不需要扩容&#xff0c;super(capacity, 1F, true);不行吗&#xff0c;干嘛还弄个装载因子0.75还中途扩容一次浪费时间。 class LRUC…...

【C语言】头文件

所有学习过C语言的朋友都熟悉这样一段代码&#xff1a; #include <stdio.h>int main(int argc, char *argv[]) {return 0; }那么&#xff0c;你真的了解 <stdio.h> 吗&#xff1f; <stdio…...

WSL (Windows Subsystem for Linux)

文章目录 Windows下使用Linux的三种方式&#xff1a;1.WSL(1)安装WSL(2)初始化Linux系统(3)安装、创建、激活 Python虚拟环境 2.虚拟机3.Docker Windows下使用Linux的三种方式&#xff1a; 1.WSL 是最简单的在 Windows 上运行 Linux 环境的方式&#xff0c;适用于日常开发和命…...

[Java] 使用 VSCode 来开发 Java

目录 前言Java 环境怎么看自己是否已经配置完成&#xff1f;安装 JDK安装 Maven 环境修改 Maven 依赖源 完善 VS Code配置插件配置 Maven配置 Maven Settings配置 Maven 可执行文件地址 前言 由于使用 VSCode 编码已经成为习惯&#xff0c;并且它确实相对其他的 IDE 较为轻量化…...

机器学习之偏差

机器学习中的偏差&#xff08;Bias&#xff09;是指模型的预测值与真实值之间的系统性误差&#xff0c;或者说模型无法准确捕捉数据中复杂模式的能力。偏差通常与模型的假设或学习能力有关&#xff0c;过高的偏差会导致模型的性能不佳&#xff0c;表现为欠拟合。 偏差的来源 模…...

微信小程序处理交易投诉管理,支持多小程序

大家好&#xff0c;我是小悟 1、问题背景 玩过微信小程序生态的&#xff0c;或许就有这种感受&#xff0c;如果收到投诉单&#xff0c;不会及时通知到手机端&#xff0c;而是每天早上10:00向小程序的管理员及运营者推送通知。通知内容为截至前一天24时该小程序账号内待处理的交…...

在C#中测试比较目录的不同方法以查看它们有哪些共同的文件

C# 中的示例“比较目录以查看它们有哪些共同的文件”使用Directory.GetFiles获取两个目录中的文件。它对文件进行排序&#xff0c;并比较两个排序后的列表以查看哪些文件位于第一个目录中、第二个目录中或两个目录中。有关其工作原理的详细信息&#xff0c;请参阅该示例。 Kur…...

2D gaussian splatting的配置和可视化

继3D gaussian splatting&#xff0c;2D gaussian splatting除了渲染新视角&#xff0c;还能够生成mesh模型。 2D gaussian splatting的配置 两者的运行环境基本一致 GitHub - hbb1/2d-gaussian-splatting: [SIGGRAPH24] 2D Gaussian Splatting for Geometrically Accurate …...

git分支管理

目录 1.Git分支管理1.1 分支创建1.2 分支删除1.3 分支合并1.4 分支的本质1.5 分支的冲突 2.Git stash2.1 git stash 3.分支管理策略3.1主分支3.2辅助分支3.3Feature分支3.4release分支3.5bugfix分支 1.Git分支管理 Git 的默认分支就是 master。你所作的commit会在master分支上…...

【Elasticsearch入门到落地】4、Elasticsearch的安装

接上篇《3、es与mysql的概念对比》 上一篇我们学习了Elasticsearch与Mysql的概念与区别。本篇我们来进行Elasticsearch的环境准备及软件安装。 一、环境准备 如果我们没有自己的Linux服务器&#xff0c;且现在正在使用的是Windows操作系统的电脑&#xff0c;那么首先我们需要安…...

如何在谷歌浏览器中开启安全浏览

在数字化时代&#xff0c;网络安全变得愈发重要。作为全球最受欢迎的网络浏览器之一&#xff0c;谷歌浏览器提供了多种功能来保护用户的在线安全。本文将详细介绍如何在谷歌浏览器中开启安全浏览&#xff0c;并额外提供一些有用的页面滚动设置、地址栏快捷搜索和跟踪防护的相关…...

短视频矩阵贴牌:打造品牌新势力的策略与实践

在数字化浪潮席卷全球的今天&#xff0c;短视频以其独特的魅力迅速崛起&#xff0c;成为连接用户与品牌的重要桥梁。企业为了快速抢占市场&#xff0c;提升品牌影响力&#xff0c;纷纷探索短视频矩阵贴牌这一新兴模式。本文将深入探讨短视频矩阵贴牌的概念、优势、实施流程及注…...

【潜意识Java】javaee中的SpringBoot在Java 开发中的应用与详细分析

目录 一、前言 二、Spring Boot 简介 三、Spring Boot 核心模块 四、Spring Boot 项目实战&#xff1a;构建一个简单的 RESTful API 1. 创建 Spring Boot 项目 2. 配置数据库 3. 创建实体类 4. 创建 JPA 仓库接口 5. 创建服务层 6. 创建控制器层 7. 测试 API 8. 运…...

linux basics

本篇文章旨在为网络安全初学者介绍linux操作系统基础。通过阅读本文&#xff0c;读者将能够对linux系统有一个初步的了解 一、openssl 1、命令&#xff1a; openssl passwd -1 123 -l参数指定使用MD5加密算法对密码"123"进行加密处理。MD5是一种常用的哈希算法,它将…...

[OpenGL] Transform feedback 介绍以及使用示例

一、简介 本文介绍了 OpenGL 中 Transform Feedback 方法的基本概念和代码示例。 二、Transform Feedback 介绍 1. Transform Feedback 简介 根据 OpenGL-wiki&#xff0c;Transform Feedback 是捕获由顶点处理步骤&#xff08;vertex shader 和 geometry shader&#xff0…...

pytorch_fid 安装笔记

目录 torch安装&#xff1a; pytorch_fid安装 torch安装&#xff1a; pip install torch2.5.0 --index-url https://download.pytorch.org/whl/cu121 pytorch_fid安装 pip install pytorch_fid 安装后&#xff0c;torch也会自动安装&#xff0c;导致torch引用报错。...

SAM大模型实践(一)

参考着segment-geospatial 项目主页的介绍&#xff0c;尝试复现一下Example-satallite的案例。 Satellite - segment-geospatialhttps://samgeo.gishub.org/examples/satellite/ 过程当中遇到了一些坑给大家做点分享&#xff0c;主要有几种情况&#xff0c;一个是torch…...

数据结构 ——前缀树查词典的实现

数据结构 ——前缀树查词典的实现 一、前缀树的概念 前缀树是一种多叉树结构&#xff0c;主要用于存储字符串。每个节点代表一个字符&#xff0c;路径从根节点到叶节点表示一个完整的字符串。前缀树的关键特征是 共享前缀&#xff0c;也就是说&#xff0c;如果两个字符串有相…...

边缘智能创新应用大赛获奖作品系列一:智能边缘计算✖软硬件一体化,开启全场景效能革命新征程

边缘智能技术快速迭代&#xff0c;并与行业深度融合。它正重塑产业格局&#xff0c;催生新产品、新体验&#xff0c;带动终端需求增长。为促进边缘智能技术的进步与发展&#xff0c;拓展开发者的思路与能力&#xff0c;挖掘边缘智能应用的创新与潜能&#xff0c;高通技术公司联…...

修改ubuntu apt 源及apt 使用

视频教程:修改ubuntu apt 源和apt 使用方法_哔哩哔哩_bilibili 1 修改apt源 1.1 获取阿里云ubuntu apt 源 https://developer.aliyun.com/mirror/ubuntu?spma2c6h.13651102.0.0.3e221b11mqqLBC 1.2 修改apt 源 vim /etc/apt/sources.list deb https://mirrors.aliyun.com/ub…...

Kafka 磁道寻址过程详解

前言 Apache Kafka 是一款高吞吐、分布式的消息流平台&#xff0c;广泛应用于实时数据处理和事件驱动系统。在 Kafka 中&#xff0c;消息是存储在磁盘上的&#xff0c;这种高效的数据读写性能得益于 Kafka 独特的磁盘存储架构和寻址机制。本文将从 Kafka 的存储结构、磁道寻址…...

GEE+本地XGboot分类

GEE本地XGboot分类 我想做提取耕地提取&#xff0c;想到了一篇董金玮老师的一篇论文&#xff0c;这个论文是先提取的耕地&#xff0c;再做作物分类&#xff0c;耕地的提取代码是开源的。 但这个代码直接在云端上进行分类&#xff0c;GEE会爆内存&#xff0c;因此我准备把数据下…...

安防监控Liveweb视频汇聚融合平台助力执法记录仪高效使用

Liveweb平台可接入的设备除了常见的智能分析网关与摄像头以外 &#xff0c;还可通过GB28181协议接入执法记录仪&#xff0c;实现对执法过程的全程监控与录像&#xff0c;并对执法轨迹与路径进行调阅回看。那么&#xff0c;如何做到执法记录仪高效使用呢&#xff1f; 由于执法记…...

酷盾安全:Edge SCDN边缘安全内容分发网络

在当今数字化迅猛发展的时代&#xff0c;互联网内容分发的高效与安全成为了企业不可忽视的重要课题。为了满足这一需求&#xff0c;酷盾安全推出了创新的Edge Secure Content Delivery Network&#xff08;Edge Scdn&#xff09;解决方案&#xff0c;它不仅融合了分布式DDoS防护…...

决策引擎技术

决策引擎&#xff08;Decision Engine&#xff09;是一种用于自动化决策过程的软件系统。它通常用于处理复杂的业务逻辑&#xff0c;根据输入的数据和预定义的规则或模型来做出决策。决策引擎在许多领域都有广泛的应用&#xff0c;如金融、保险、医疗、供应链管理等。 在Java中…...

Servlet学习中遇到的一些问题及解决

错误&#xff1a;JavaWeb-错误&#xff1a;类xxx不是Servlet 解决&#xff1a;可能是Tomcat版本不匹配导致&#xff0c;更换Tomcat版本解决问题 错误&#xff1a;在自定义的Servlet类中不能添加 WebServlet 注解 解决&#xff1a;可能是WebServlet版本不匹配&#xff0c;更换…...

oracle开窗函数笔记、over()笔记

文章目录 开窗函数、组函数、分析函数概念聚合函数和分析函数的区别partition by后面也可以跟多个字段 开窗函数一定要加 聚合函数、或分析函数吗&#xff0c;否则会报错lag()和lead()的用法lag和lead实战开窗函数可以和其他函数一起使用吗? TODO开窗函数中的count(1)是什么意…...

深度学习面试相关-2024.12.15记录

深度学习 面试相关- 2024.12.15记录 目录 深度学习 面试相关- 2024.12.15记录整体常问问题1数学基础1.1 概率统计1.2 线代 2机器学习算法2.1 深度学习算法2.2 机器学习算法 整体常问问题 https://www.nowcoder.com/discuss/353154899112304640 1数学基础 1.1 概率统计 htt…...

CSS|07 标准文档流

标准文档流 一、什么是标准文档流 在制作的 HTML 网页和 PS 画图软件画图时有本质上面的区别: HTML 网页在制作的时候都得遵循一个“流的规则:从左至右、从上至下。 使用 Ps 软件画图时可以在任意地方画图。 <!DOCTYPE html> <html lang"en"> <hea…...

1 JVM JDK JRE之间的区别以及使用字节码的好处

JDK jdk是编译java源文件成class文件的&#xff0c;我们使用javac命令把java源文件编译成class文件。 我们在java安装的目录下找到bin文件夹&#xff0c;如下图所示: 遵循着编译原理&#xff0c;把java源文件编译成JVM可识别的机器码。 其中还包括jar打包工具等。主要是针对…...

ubuntu安装8812au驱动却无法加载网卡的问题

驱动GIT地址 https://github.com/aircrack-ng/rtl8812au按照里面提示安装驱动 输入 sudo dkms status查看驱动是否安装成功 接入网卡&#xff0c;看看ifconfig能否输出网卡 如果不行 使用sudo dmesg -w插拔网卡看看输出 如果输出为: load module with unavailable key is …...

Eureka学习笔记-服务端

Eureka学习笔记 服务端 模块设计 Resources &#xff1a;这部分对外暴露了一系列的 Restful 接口。Eureka Client 的注册、心跳、获取服务列表等操作都需要调用这些接口。另外&#xff0c;其他的 Server 在同步 Registry 时也需要调用这些接口。Controller &#xff1a;这里提…...

LangChain

文章目录 一、LangChain 是什么&#xff1f;二、核心概念1. LLM Wrappers2. Prompt Templates3. Indexes4. Chains5. Agents 三、工作流程四、应用场景示例一&#xff1a;简单的语言模型调用示例二&#xff1a;使用Prompt Templates&#xff08;提示模板&#xff09;示例三&…...

搭建分布式Hive集群

title: 搭建分布式Hive集群 date: 2024-11-29 23:39:00 categories: - 服务器 tags: - Hive - 大数据搭建分布式Hive集群 本次实验环境&#xff1a;Centos 7-2009、Hadoop-3.1.4、JDK 8、Zookeeper-3.6.3、Mysql-5.7.38、Hive-3.1.2 功能规划 方案一&#xff08;本地运行模…...

Scala的惰性求值:深入理解与实践

在编程中&#xff0c;我们经常需要处理那些计算成本高昂或者可能永远不会用到的值。在这种情况下&#xff0c;惰性求值&#xff08;Lazy Evaluation&#xff09;是一种非常有用的策略。它允许我们推迟计算&#xff0c;直到这些值真正需要被使用。Scala&#xff0c;作为一种多功…...

游戏引擎学习第54天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾 我们现在正专注于在游戏世界中放置小实体来代表所有的墙。这些实体围绕着世界的每个边缘。我们有活跃的实体&#xff0c;这些实体位于玩家的视野中&#xff0c;频繁更新&#xff0c;而那些离玩家较远的实体则以较低的频率运…...

QT绘制同心扇形

void ChartForm::paintEvent(QPaintEvent *) {QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);// 设置抗锯齿painter.save();// 设置无边框&#xff08;不需要设置QPen&#xff0c;因为默认是不绘制边框的&#xff09;QPen pen(Qt::NoPen);// QPen pen…...

梳理你的思路(从OOP到架构设计)_浅尝架构师的滋味02

目录 1、 App开发者的职责&#xff1a;买主提供需求知识&#xff0c;App开发者帮他写代码 撰写的代码 撰写代码&#xff0c;将装配(扩充)到 2、 从生活中体会 基於軟硬整合觀點“两种知识” ​编辑 1、 App开发者的职责&#xff1a;买主提供需求知识&#xff0c;App开发者帮…...

使用VLC 搭建 RTSP 服务器

第一步&#xff1a;打开 VLC &#xff0c;媒体--->流 第二步&#xff1a;添加一个选择本地的文件&#xff0c;然后点击选择"串流" 第三步&#xff1a;确认你选择的文件&#xff0c;然后点击下一个 第四步&#xff1a; 配置 选择的视频文件使用哪种 流输出&#xf…...

什么是大型语言模型

大型语言模型简介 大型语言模型 (LLM) 是一种深度学习算法&#xff0c;可以使用非常大的数据集识别、总结、翻译、预测和生成内容。 NVIDIA 开发者计划 想要了解有关 NIM 的更多信息&#xff1f;加入 NVIDIA 开发者计划&#xff0c;即可免费访问任何基础设施云、数据中心或个…...

游卡,科锐国际,蓝禾,汤臣倍健,顺丰,途游游戏25秋招内推

游卡&#xff0c;科锐国际&#xff0c;蓝禾&#xff0c;汤臣倍健&#xff0c;顺丰&#xff0c;途游游戏25秋招内推 ①科锐国际25届秋招补录 人力资源类岗位&#xff0c;补录城市&#xff1a;上海&#xff0c;苏州&#xff0c;锦州&#xff1b;全日制公办本科及以上 25届应届毕业…...

Linux -- 线程控制相关的函数

目录 pthread_create -- 创建线程 参数 返回值 代码 -- 不传 args&#xff1a; 编译时带 -lpthread 运行结果 为什么输出混杂&#xff1f; 如何证明两个线程属于同一个进程&#xff1f; 如何证明是两个执行流&#xff1f; 什么是LWP&#xff1f; 代码 -- 传 args&a…...

【Linux】Linux内核启动流程分析

Linux 内核的启动流程要比 uboot 复杂的多&#xff0c;涉及到的内容也更多&#xff0c;因此我们大致的了解一下Linux 内核的启动流程即可。 Linux启动流程 启动过程可以分为以下几个主要步骤&#xff1a; 1.引导加载程序&#xff08;Bootloader&#xff09;阶段 Linux 内核的…...

【uniapp蓝牙】基于native.js链接ble和非ble蓝牙

【uniapp蓝牙】基于native.js链接ble和非ble蓝牙 uniapp不是仅支持低功耗蓝牙&#xff08;基础蓝牙通讯不支持&#xff09;&#xff0c;有些可能需要基础蓝牙。我现在同步我的手机蓝牙列表低功耗&#xff0c;基础蓝牙都支持 /*** author wzj* 通用蓝牙模块封装* 搜索 ble 和非…...

OpenGL ES 03 加载3张图片并做混合处理

OpenGL ES 02 加载3张图片并做混合处理 什么是纹理单元纹理单元的作用使用纹理单元的步骤详细解释加载图片并绑定到到GPU纹理单元采样器的设置1.设置采样器变量的纹理单元编号&#xff0c;目的是为了告诉纹理采样器&#xff0c;从哪个纹理单元采集数据2.如果你没有显式地设置采…...