探讨==和equals的区别和联系,为什么equals()和hashcode()要一起重写?

news2024/11/15 15:45:03

(一) 探讨==和equals的区别和联系?

面试考题:《关于和equals的区别》,该怎么回答完美呢?

可以这样回答:

(1)对于 == 简单来说比较的是指相等
①:对于基本数据类型,则直接比较的是对应变量存储的数值是否相等。
②:对于引用数据类型而言,比较的是其引用对象的地址是否相等。

(2)equals注意是一个方法,它对应的是判断对象是否相等,如果是基本数据类型的话无法使用,不过如果是基本数据类型对应的封装类则可以使用。

(二)为什么实体类的equals()和hashcode()要一起重写?

1、先说一下equals()方法

① 如果我们比较的对象实体类中没有对equals方法重写,那我们比较的是引用对象的地址。

② 如果实体类中对equals方法进行重写,则是按照实体类中equals的方法对两个对象进行判断是否相等,一般重写都是比较对象的内容是否相等,比如String类中的重写方法!!!

在这里插入图片描述
举个例子,这个例子很典型:
在这里插入图片描述
打印结果:
在这里插入图片描述

2、探讨一下HashCode的数值

Java中的对象是JVM在管理,JVM会在她认为合适的时候对对象进行移动,比如,在某些需要整理内存碎片的GC算法下发生的GC。此时,对象的地址会变动,但hashcode不会改变。就好比现实中一个人出生在A城市,成年工作后落户到了B城市,但是身份证号是不会变的。

(1)什么是hashcode?

每个对象都可以计算hashcode,首先一个对象肯定有物理地址,将对象的物理地址转换成一个整数,然后该整数通过hash函数的算法就得到了hashcode,hashcode就是在hash表中对应的位置。

物理地址指对象存放在内存中的地址,hashcode代表对象的地址在hash表中的位置。(这里一定要注意hashcode不是对象在内存中的地址,仅仅代表了对象在hash表中的位置)

例:有一个Hash表,表中有 hashcode为1、hashcode为2…hashcode为5这样5个位置,有一个对象A,假设A的物理地址转化为整数是17,通过特定的hash函数算出来的hashcode值为2(假设用物理地址%5来计算hashcode),则对象A应该在hash表中的2的位置。如果有一个对象B,算出来的hashcode值为3,则B应该在hashcode表中3的位置。如果有一个对象C,他计算出来的hashcode也等于2,则证明C和A的物理地址是一样的(假设hash函数正确,既不同的x值算出来的h(x)不同),则对象C和对象A应该是相等的。

Java中的HashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。即在散列集合包括HashSet、HashMap以及HashTable里,对每一个存储的桶元素都有一个唯一的"块编号",即它在集合里面的存储地址;当你调用contains方法的时候,它会根据hashcode找到块的存储地址从而定位到该桶元素。

(2)判断两个对象相等可以用hashcode比较吗?

不可以,必须用equals方法,因为对于两个不同对象的hashcode值可能计算出来是相同的,不同的hashcode不同的对象一定不同。

另外一点,如果覆写了equals方法,必须覆写hashcode方法,原因是默认的hashcode是将对象的存储地址进行映射。而且逻辑上,如果两个对象的equals方法返回是相等的,那么它们的hashcode必须相等;反之不一定成立。

(3)那么重写实体类的equlas方法一定要重写hashcode方法吗?

答案是不一定,需要根据具体的情况进行判断,但是建议两个方法一起重写!
①你如果只是用来对对象进行简单的判断的话,那么你可以只重写equals方法就可以
②但是如果你使用HashSet集合进行存储数据元素的时候,那一定要对hashcode方法进行重写,否则会出现一些错误,下面举个例子:

第一种状况:只重写equals方法,不重写hashcode方法时

实体类:



@Data
@NoArgsConstructor
@AllArgsConstructor
public class TestUser1 {

        private String name;
        private Integer age;

    @Override
    public boolean equals(Object o) {
        System.out.println("实体类重写的equals方法");
        if(o == this)
            return true;
        if(!(o instanceof TestUser1))
            return false;
        if (o instanceof TestUser1) {

            TestUser1 user = (TestUser1)o;
            return user.name.equals(name);
            //return user.name.equals(name) && user.age.equals(age);
        }
        return false;
    }

测试方法:

package com.blog.test;

import com.blog.pojo.TestUser1;

import java.util.HashSet;

public class Test1 {
    public static void main(String[] args) {
        TestUser1 user1 = new TestUser1("张三");
        TestUser1 user2 = new TestUser1("张三");
        
        HashSet<TestUser1> users = new HashSet<>();
        users.add(user1);
        System.out.println(user1.equals(user2));
        System.out.println("-----分界线---------");
        System.out.println(users.contains(user2));
    }
}

结果分析:
在这里插入图片描述
这时候如果上司交给我们的任务说是集合中不可以存在名字相同的两个人,那么这是不是出现问题了呢,这就是没有重写hashcode方法所导致的问题。

第二种状况:同时重写equals方法和hashcode方法

实体类:

package com.blog.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class TestUser1 {
        private String name;
    @Override
    public boolean equals(Object o) {
        System.out.println("实体类重写的equals方法");
        if(o == this)
            return true;
        if(!(o instanceof TestUser1))
            return false;
        if (o instanceof TestUser1) {

            TestUser1 user = (TestUser1)o;
            return user.name.equals(name);
            //return user.name.equals(name) && user.age.equals(age);
        }
        return false;
    }
    @Override
    public int hashCode() {
        System.out.println("实体类重写的hashcode方法");
        result = name.hashCode();
        return result;
    }

}

测试方法:

    public static void main(String[] args) {
        TestUser1 user1 = new TestUser1("张三");
        TestUser1 user2 = new TestUser1("张三");
        TestUser1 user3 = new TestUser1("李四");
        HashSet<TestUser1> users = new HashSet<>();
        users.add(user1);
        System.out.println(user1.equals(user2));
        System.out.println("-----分界线---------");
        System.out.println(users.contains(user2));
    }

在这里插入图片描述

在这里我们就可以发现其实使用contains()方法的时候,他会先对hashcode值进行比较,如果两个对象的hashcode数值不对的话,会直接返回false,然后在用equals()方法进行比较。

大家有兴趣的话可以去查看一下源码,基本上也是这样,在这里由于时间关系就不一一介绍了。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

项目实战-瑞吉外卖day01(B站)

瑞吉外卖-Day01课程内容软件开发整体介绍瑞吉外卖项目介绍开发环境搭建后台登录功能开发后台退出功能开发1. 软件开发整体介绍作为一名软件开发工程师,我们需要了解在软件开发过程中的开发流程&#xff0c; 以及软件开发过程中涉及到的岗位角色&#xff0c;角色的分工、职责&am…

Vland:像乐高一样搭建元宇宙|开发者说

社交达人金秋远每年会组织和参加数以百计的活动——既有线下也有线上&#xff0c;既有德州扑克也有创业交流&#xff0c;既有客户回访也有校友叙旧。 活跃于各种社交活动&#xff0c;是金秋远在贝恩咨询为 500 强企业担任战略顾问时养成的习惯。由于喜欢研究「人与人的连接」&…

如何用Python把篮球和鸡联系起来

文章目录画个球让球转起来画个球 不管篮球和不和鸡联系起来&#xff0c;都首先得有个球&#xff0c;或者说要有一个球面&#xff0c;用参数方程可以表示为 xrcos⁡ϕcos⁡θyrcos⁡ϕsin⁡θzrsin⁡ϕ\begin{aligned} x & r\cos\phi\cos\theta\\ y & r\cos\phi\sin\th…

STM32 EXTI外部中断

本文代码使用 HAL 库。 文章目录前言一、什么是外部中断&#xff1f;二、外部中断中断线三、STM32F103的引脚复用四、相关函数&#xff1a;总结前言 一、什么是外部中断&#xff1f; 外部中断 是单片机实时地处理外部事件的一种内部机制。当某种外部事件发生时&#xff0c;单片…

13 nuxt3学习(新建页面 内置组件 assets 路由)

新建页面 Nuxt项目中的页面是在 pages目录 下创建的 在pages目录创建的页面&#xff0c;Nuxt会根据该页面的目录结构和其文件名来自动生成对应的路由。页面路由也称为文件系统路由器&#xff08;file system router&#xff09;&#xff0c;路由是Nuxt的核心功能之一 方式一…

DHTMLX Suite 8.0 重大发布,新增更多新主题、热图图表、辅助功能支持功能

DHTMLX Suite 是一个用于构建跨浏览器Web应用和移动应用的强大JavaScript UI库。DHTMLX UI 组件库允许您更快地构建跨平台、跨浏览器 Web 和移动应用程序。它包括一组丰富的即用式 HTML5 组件&#xff0c;这些组件可以轻松组合到单个应用程序界面中。 DHTMLX Spreadsheet正版试…

动态网站开发讲课笔记04:Servlet基础

文章目录零、本节学习目标一、Servlet基础&#xff08;一&#xff09;Servlet概述1、Servlet是什么2、Servlet容器3、Servlet应用程序的体系结构&#xff08;二&#xff09;Servlet的特点1、功能强大2、可移植3、性能高效4、安全性高5、可扩展&#xff08;三&#xff09;Servle…

数据结构刷新知识总结,为了与题目分开,特地在这里开一篇博客

文章目录二叉树、树、森林的转换二叉树的五个特性常用算法总结常用算法详解图的概念堆排序哈希查找二叉树、树、森林的转换 树转二叉树 二叉树转树 森林转二叉树 二叉树转森林 二叉树的五个特性 性质1&#xff1a;在二叉树的第i层上至多有2i-1个结点性质2&#xff1a;深度为…

Android动态获取权限(详细教程附代码)

Android动态获取权限概述动态获取权限具体实现layout布局代码回调函数onRequestPermissionsResult权限判断工具类清单文件方式一&#xff1a;懒汉式方式二&#xff1a;饿汉式概述 如果是android6.0以下的版本&#xff0c;只需要在manifest声明对应的权限即可。但是这样会大大降…

美颜sdk动态贴纸的实现流程

随着移动互联网时代的到来&#xff0c;各式各样的 APP层出不穷&#xff0c;从最初的微信、 QQ到如今的抖音、快手等等&#xff0c;再到如今的微博、小红书等等&#xff0c;各式各样的 APP不断涌现。从最开始简单的图片展示到视频聊天&#xff0c;再到现如今丰富多样的各种动态贴…

rip题解

1.查看文件保护机制 使用的是新版本的checksec 2.拖入IDA分析 查壳 是一个64文件&#xff0c;拖入64位IDA 这个文件就是我们要攻击的服务器中的一个进程的代码&#xff0c;进程就是一个正在运行的程序 分析敏感函数 打开字符串窗口 跟进&#xff0c;光标点在command&#x…

Linux: ARM GIC只中断CPU 0问题分析

文章目录1. 前言2. 分析背景3. 问题4. 分析4.1 ARM GIC 中断芯片简介4.1.1 中断类型和分布4.1.2 拓扑结构4.2 问题根因4.2.1 设置GIC SPI 中断CPU亲和性4.2.2 GIC初始化&#xff1a;缺省的CPU亲和性4.2.2.1 boot CPU亲和性初始化流程4.2.2.1 其它非 boot CPU亲和性初始化流程5.…

【微信小程序】-- 全局配置 -- window - 下拉刷新 上拉触底(十六)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &…

模型实战(6)之Alex实现图像分类:模型原理+训练+预测(详细教程!)

Alex实现图像分类:模型原理+训练+预测 图像分类或者检索任务在浏览器中的搜索操作、爬虫搜图中应用较广,本文主要通过Alex模型实现猫狗分类,并且将可以复用的开源模型在文章中给出!!!数据集可以由此下载:Data本文将从以下内容做出讲述: 1.模型简介及环境搭建2.数据集准…

微纳制造期末复习

章节分为六个模块&#xff1a; 1. 微纳制造中的材料 2.光刻技术 3.微纳制造中使用的技术 4.刻蚀 5.沉积 7.微纳刻蚀 根据导电性区分材料&#xff1a;导体&#xff0c;半导体&#xff0c;绝缘体 晶体&#xff1a;长程有序 多晶&#xff1a;短程有序 非晶&#xff1a;无序…

八 SpringMVC【拦截器】登录验证

目录&#x1f6a9;一 SpringMVC拦截器✅ 1.配置文件✅2.登录验证代码&#xff08;HandlerInterceptor&#xff09;✅3.继承HandlerInterceptorAdapter&#xff08;不建议使用&#xff09;✅4.登录页面jsp✅5.主页面&#xff08;操作页面&#xff09;✅6.crud用户在访问页面时 只…

【算法】PatchMatch立体匹配算法_原理解析

目录 前言 原理解析 1.倾斜支持窗口&#xff08;Slanted Support Windows&#xff09; 什么是视差平面&#xff1f; 为什么视差和像素坐标点之间的关系可以解释为平面方程&#xff1f; 视差平面的通用参数方程和点加法向量方程 什么是倾斜支持窗口&#xff1f; 2.基于倾…

宏基因组鉴定病毒流程中需要的生物信息工具

谷禾健康 许多流行病的爆发都是病毒引起的&#xff0c;面对新的传染性基因组出现的最佳策略是及时识别&#xff0c;以便于在感染开始时立即实施相应措施。 目前可用的诊断测试仅限于检测新的病理因子。适用于同时检测存在的任何病原体的高通量方法可能比使用基于当前方法的大量…

Mel Spectrogram

参考链接&#xff1a; Short-time Fourier transform - MATLAB stft- MathWorks 中国 https://medium.com/analytics-vidhya/understanding-the-mel-spectrogram-fca2afa2ce53 a spectrogram as a bunch of FFTs stacked on top of each other. 给出hop length后&#xff0…

TMP耗时较高的优化问题

1&#xff09;TMP耗时较高的优化问题 ​2&#xff09;Unity重载Object后&#xff0c;如何判定物体是否为空 3&#xff09;SRP Batch在添加unity_SpecCube后的问题 4&#xff09;堆内存会持续上升&#xff0c;如何用UWA报告来分析 这是第326篇UWA技术知识分享的推送&#xff0c;…