【Java】Object类中的equals()和hashCode()

一、Object类简介

Java中,Object类是Java的 java.lang 包内的核心类,Object类是所有类的祖先类,每个类都直接或间接地继承Object类,一个类如果没有使用extends关键字明确地继承一个类的时候,那它就是Object的子类。

刚学继承的小明跟你开始显摆了。他说:我这有Animal类,Dog类,和Cat类,只有Dog类继承了Animal类,所以只有Dog类有父类。你冷笑一声,说:这里看似只有一个爹,实际上有两个爹。没错,Animal类和Cat类都是Object类的子类。

也就是说,无需显式定义一个类继承Object类,即下面的代码是等价的。

class Animal{}class Animal extends Object {}

Object类作为所有类的父类,可以接收任何类的对象。

就像爱德华将Java的所有类都视为自己的儿子。

 Object类型的变量只能用于作为各种值的通用持有者,要想对其中的内容进行具体的操作,还需要清楚对象的原始类型并进行相应的类型转换。

class Cat {}class Dog {}public class Test{public static void main(String[] args){Object cat = new Cat();Object dog = new Dog();Cat cat_real = cat;}
}

Object类中定义了一些基础方法,任何一个Java类都通过继承自动获得Object类中的方法,虽然大多数方法在不同的类中都会根据需要进行重写覆盖,但是这些重新的方法仍需遵守Object类中方法的基本行为和契约。

一些常用的Object类中的方法:

1. equlas( Object obj)

比较内存地址是否指向相同,比较句柄的引用是否相同

2. getClass()

获取类的信息 - - 反射领域

3. hashCode()

散列码 - - 根据地址生成,散列码 = hash = 哈希

4. notify()

唤醒等待的线程

5. notifyAll()

唤醒等待的所有线程

6. toString()

输出对象的类型和内存地址

7. wait ()

线程进入等待状态,让出CPU和锁

二、equals() 方法

Object 类中的 equals方法用于检测一个对象是否等于另外一个对象。在Object类中,这 个方法将判断两个对象是否具有相同的引用。如果两个对象具有相同的引用,它们一定是相 等的。从这点上看,将其作为默认操作也是合乎情理的。然而,对于多数类来说,这种判断 并没有什么意义。看看Object类中equals的实现源码:

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

非常简陋的 “==” 实现判断。我们知道 “==” 判断的是两个变量指向的地址是否相同(对象是否是同一地址),所以当子类中未重写equals方法时,默认调用Object类的equals方法,判断两个变量是否指向同一块内存空间,大多数的情况下的结果是false

1、equals的特性

Java要求equals方法具有下面的特性:

1. 自反性

对于任何非空引用x, x.equals(x)应该返回true;

2. 对称性

对于任何引用x和y,当且仅当y.equals(x)返回true,x.equals(y)返回true;

3. 传递性

对于任何引用x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,则z.equals(y)也要返回true;

4. 一致性

如果x和y的引用对象没有发生变化,反复调用x.equals(y)应该返回同样的结果;

5. 非空

对于任何非空引用x, x.equals(null)应该返回false;

2、 equals() 方法和“==”的区别

1. == 操作符

== 是一个 比较运算符,用于比较两个对象的引用是否相同,即它判断两个引用变量是否指向同一个内存地址。

  • 对于基本数据类型(int,short、byte、long、char、boolean、float、double),==比较值是否相同;
  • 对于引用数据类型(对象、数组、接口),== 用于比较两个引用是否指向同一个对象(即内存地址是否相同)。
int a = 10;
int b = 10;
System.out.println(a == b);  // true,比较的是值String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1 == str2);  // false,比较的是内存地址,不同的对象实例

a==b 比较的是两个 int 类型变量的值,因此返回 true。然而,str1 == str2 返回 false,即使它们的值相同,因为 new String("Hello") 创建了两个不同的 String 对象,虽然它们的内容相同,但它们的内存地址不同。

2. equals() 方法

equals()是 object 类中的一个方法,用于比较两个对象的内容是否相等。 Object 类的默认实现使用==比较引用,因此默认行为是比较两个对象的引用是否相同。

但是,很多类(如 String、Integer、List 等)会重写equals()方法,使用对象的内容来判断是否相等,而不是简单地比较内存地址。

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1.equals(str2));  // true,比较的是内容

str1.equals(str2)返回 true,因为 String 类重写了字符串的equals()方法,比较的是两个内容是否相同,而不仅仅是它们的内存地址。

3. equals 和 == 的区别

== equals() 方法
比较内容比较的是引用是否相同,即内存地址比较的是对象的内容,依据类的实现
适用对象基本数据类型和引用数据类型主要用于引用数据类型(对象、数组等)
默认行为对于引用类型,默认比较引用地址(内存地址)默认比较引用地址(同 ==
是否被重写无需重写会被许多类重写

3、总结

  • == 是用来比较两个对象的引用(内存地址)是否相同,对于基本数据类型比较的是值。
  • equals() 方法是用来比较两个对象的内容是否相equals()同,通常在类中会重写该方法来判断内容的相等。

三、hashCode() 方法

来看java.lang包中对hashCode的注解:

返回对象的哈希码值。由于java.uti.提供的哈希表等哈希表的好处,支持此方法。HashMap。

hashCode的通用协议是:在Java应用程序的执行过程中,每当在同一个对象上多次调用hashCode方法时,只要对象上的equals比较中使用的信息没有被修改,该方法就必须始终返回相同的整数。此整数不需要在应用程序的一次执行到同一应用程序的另一次执行之间体持一致。如果根据equals(Object)方法,两个对象相等,则对这两个对象中的每一个调用hashCode方法必须产生相同的整数结果。如果两个对象根据equals(Object)方法不相等,则不需要对这两个对象中的每一个调用hashCode方法必须产生不同的整数结果。

然而,程序员应该意识到,为不等对象生成不同的整数结果可能会提高哈希表的性能,在合理可行的情况下,Object类定义的hashCode方法确实会为不同的对象返回不同的整数。(这通常是通过将对象的内部地址转换为整数来实现的,但Java"编程语言不需要这种实现技术。)

返回值:此对象的哈希码值。

native —— 本地方法,底层使用C++实现。hashCode方法将对象的地址映射为一个 int 类型的数据。这样,对象就可以存储到哈希表中,同时可以从哈希表中快速定位和查询对象

 简单来说就是,hashCode()方法返回一个整数值,这个值代表了对象在内存中的哈希码。对于基于哈希表的数据结构如HashMap、HashSet,hashcode()的表现至关重要。哈希码决定了对象存储的位置,从而影响性能。

1、hashCode() 的特性

1. 一致性

如果对象的状态没有变化,调用hashCode()方法应始终返回相同的值;

2. equals() 和 hashCode() 的一致性

如果两个对象通过 equals() 方法判断是相等的,那么它们的hashCode() 值必须相等,反之, equals()判断两个对象不相等,则它们的hashCode() 值一定不相等。

2、hashCode() 和 equals()必须一起被重写

因为使用 hashCode 方法的时候,是在哈希表中进行定位和查询对象,如果重写了equals方法,改变了原来判断对象是否相等的逻辑,那么有可能会导致hashCode方法判断相同的对象,equals方法判断不相同,或者hashCode判断为不同,equals判断为相同。

之所以子类重写equals方法的时候,一定要重写hashCode方法就是要保证hashCode计算相同的对象equals也能计算相同。

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

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

相关文章

DEEPSEEK与GPT等AI技术在机床数据采集与数字化转型中的应用与影响

随着人工智能(AI)技术的迅猛发展,深度学习、自然语言处理等先进技术开始广泛应用于各行各业。在制造业尤其是机床行业,AI技术的融合带来了巨大的变革,尤其在机床数据采集与机床数字化方面的应用。本文将探讨DEEPSEEK、…

网络工程师 (31)VLAN

前言 VLAN(Virtual Local Area Network)即虚拟局域网,是一种将物理局域网划分成多个逻辑上独立的虚拟网络的技术。 一、定义与特点 定义:VLAN是对连接到的第二层交换机端口的网络用户的逻辑分段,不受网络用户的物理位置…

【Qt之·类QTextCursor】

系列文章目录 文章目录 前言一、概述1.1 QTextCursor类的作用和用途 二、QTextCursor类的常用方法2.1 setPosition()方法:设置光标的位置2.2 insertText()方法:在光标位置插入文本。2.3 deleteChar()方法:删除光标位置处的字符。2.4 movePosi…

Visual Studio 中的键盘快捷方式

可打印快捷方式备忘单 Visual Studio 的常用键盘快捷方式 本部分中的所有快捷方式都将全局应用(除非另有指定)。 “全局”上下文表示该快捷方式适用于 Visual Studio 中的任何工具窗口。 生成:常用快捷方式 命令键盘快捷键命令 ID生成解决…

如何免费白嫖 Deepseek API 接口

今天我将教大家如何利用网络空间测绘搜索引擎「Fofa」来寻找已经部署并开放 Deepseek 接口的服务。以下是详细步骤: 1. 访问 Fofa 搜索引擎 首先,打开 Fofa 搜索引擎的网站:https://fofa.info 2. 搜索开放的 Deepseek 接口 在搜索框中输入…

如何评估云原生GenAI应用开发中的安全风险(下)

以上就是如何评估云原生GenAI应用开发中的安全风险系列中的上篇内容,在本篇中我们介绍了在云原生AI应用开发中不同层级的风险,并了解了如何定义AI系统的风险。在本系列下篇中我们会继续探索我们为我们的云原生AI应用评估风险的背景和意义,并且…

Mybatis源码02 - 初始化基本过程(引导层部分)

初始化基本过程(引导层部分) 文章目录 初始化基本过程(引导层部分)一:初始化的方式及引入二:初始化方式-XML配置文件1:MyBatis初始化基本过程2:创建Configuration对象的过程2.1&…

Baumer工业相机堡盟工业相机如何实现一次图像采集同时检测产品的5个面甚至多个面(C#)(NEOAPI SDK)

Baumer工业相机堡盟工业相机如何实现一次图像采集同时检测产品的5个面甚至多个面(C#)(NEOAPI SDK) Baumer工业相机光学棱镜反射图像的技术背景工业相机ROI功能的技术背景图像处理多线程功能的技术背景Baumer工业相机通过棱镜同时检…

ASP.NET Core 如何使用 C# 从端点发出 GET 请求

使用 C#,从 REST API 端点获取 JSON;如何从 REST API 接收 JSON 数据。 本文需要 ASP .NET Core,并兼容 .NET Core 3.1、.NET 6和.NET 8。 要将数据发布到端点,请参阅本文。 使用 . 从端点发布 GET 数据非常容易HttpClient&…

基于微信小程序的博物馆预约系统的设计与实现

hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 🦁作者简介:一名喜欢分享和记录学习的在校大学生…

Mybatis快速入门与核心知识总结

Mybatis 1. 实体类(Entity Class)1.1 实体类的定义1.2 简化编写1.2.1 Data1.2.2 AllArgsConstructor1.2.3 NoArgsConstructor 2. 创建 Mapper 接口2.1 Param2.2 #{} 占位符2.3 SQL 预编译 3. 配置 MyBatis XML 映射文件(可选)3.1 …

ios通过xib创建控件

之前写过ios动态创建控件及添加事件,纯手工代码写控件,虽然比较灵活,但是就是代码量比较多。这次我们通过xib来创建app下载列表项 AppView.xib。一个imageview,一个label,一个button构成 1.创建AppView.xib 2.再创建xib对应的mode&#xff0…

MybatisPlus常用增删改查

记录下MybatisPlus的简单的增删改查 接口概述 Service和Mapper区别 Mapper简化了单表的sql操作步骤(CRUD),而Serivce则是对Mapper的功能增强。 Service虽然加入了数据库的操作,但还是以业务功能为主,而更加复杂的SQL…

deepseek+kimi一键生成PPT

1、deepseek生成大纲内容 访问deepseek官方网站:https://www.deepseek.com/ 将你想要编写的PPT内容输入到对话框,点击【蓝色】发送按钮,让deepseek生成内容大纲,并以markdown形式输出。 等待deepseek生成内容完毕后&#xff0c…

1312:【例3.4】昆虫繁殖

1312:【例3.4】昆虫繁殖 时间限制: 1000 ms 内存限制: 65536 KB 提交数:60386 通过数: 29787 【题目描述】 科学家在热带森林中发现了一种特殊的昆虫,这种昆虫的繁殖能力很强。每对成虫过xx个月产yy对卵,每对卵要过两个月长成成虫…

【牛客】动态规划专题一:斐波那契数列

文章目录 DP1 斐波那契数列法1&#xff1a;递归法2&#xff1a;动态规划法3&#xff1a;优化空间复杂度 2.分割连接字符串3. 给定一个字符串s和一组单词dict&#xff0c;在s中添加空格将s变成一个句子 DP1 斐波那契数列 法1&#xff1a;递归 // 递归 #include <iostream>…

RDK新一代模型转换可视化工具!!!

作者&#xff1a;SkyXZ CSDN&#xff1a;SkyXZ&#xff5e;-CSDN博客 博客园&#xff1a;SkyXZ - 博客园 之前在使用的RDK X3的时候&#xff0c;吴诺老师wunuo发布了新一代量化转换工具链使用教程&#xff0c;这个工具真的非常的方便&#xff0c;能非常快速的完成X3上模型的量化…

2025.2.8——一、[护网杯 2018]easy_tornado tornado模板注入

题目来源&#xff1a;BUUCTF [护网杯 2018]easy_tornado 目录 一、打开靶机&#xff0c;整理信息 二、解题思路 step 1&#xff1a;分析已知信息 step 2&#xff1a;目标——找到cookie_secret step 3&#xff1a;构造payload 三、小结 一、打开靶机&#xff0c;整理信…

2. UVM的基本概念和架构

文章目录 前言1. UVM的基本概念1.1 UVM的核心组件1.2 UVM的基本架构1.3 UVM的工作流程 2. UVM的架构2.1 UVM的层次结构2.2 UVM的组件交互 3. 总结 前言 首先&#xff0c;得确定UVM的基本概念和架构包含哪些关键部分。我回忆起UVM的核心组件&#xff0c;比如uvm_component、uvm…

VMware Workstation创建虚拟机

目录 创建新的虚拟机 虚拟机快照功能 虚拟机添加空间 其他注意事项 创建新的虚拟机 打开VMware Workstation&#xff1a;启动软件后&#xff0c;点击“创建新的虚拟机”。 选择安装方式&#xff1a; 典型安装&#xff1a;适合大多数用户&#xff0c;会自动完成大部分配置…