HashCode()和equals()的区别

2023-05-16

文章目录

    • HashCode简介
    • equals简介
    • 1、类中重写HashCode和equals方法比较两个对象是否相等
    • 2、HashSet保证元素的唯一性

HashCode简介

hashCode()方法的作用是获取哈希码,返回的是一个int整数

Object类中的hashCode()方法定义如下

public native int hashCode();

哈希码的作用是确定对象在哈希表的索引下标。比如HashSet和HashMap就是使用了hashCode方法确定索引下标。如果两个对象返回的hashCode相同,就被称为“哈希冲突”。

equals简介

equals()方法的作用很简单,就是判断两个对象是否相等,equals()方法是定义在Object类中,而所有的类的父类都是Object,所以如果不重写equals方法则会调用Object类的equals方法。

Object类中的equals()方法定义如下

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

在equals()方法中的==,那么在Java中有什么含义呢,

我们都知道在Java中分为基本数据类型和引用数据类型。那么==在这两个类型中作用是不一样的。

  • 基本数据类型:比较的是==两边值是否相等
  • 引用数据类型:比较的是==两边内存地址是否相等

基本数据类型包括:byte,short,char,int,long,float,double,boolean

而通过Java文档中的equals()方法描述,所有要实现自己的equals()方法都要遵守下面几个规则

  • 自反性:对于任何对象x,x.equals(x)应该返回true。
  • 对称性:对于任何两个对象x和y,如果x.equals(y)返回true,那么y.equals(x)也应该返回true。
  • 传递性:对于多个对象x,y,z,如果x.equals(y)返回true,y.equals(z)返回true,那么y.equals(z)也应该返回true。
  • 一致性:对于两个非空对象x,y,在没有修改此对象的前提下,多次调用返回的结果应该相同。
  • 对于任何非空的对象x,x.equals(null)都应该返回false。

1、类中重写HashCode和equals方法比较两个对象是否相等

  • 两个对象通过equals比较是相等的,那么HashCode肯定相等。

  • 两个对象通过HashCode比较是相等的,那么equals不一定相等。

  • 因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖

面试题:
重写equals()方法就可以比较两个对象是否相等,为什么还要重写hashcode()方法呢?

因为HashSet、HashMap底层在添加元素时,会先判断对象的hashCode是否相等,如果hashCode相等才会用equals()方法比较是否相等。换句话说,HashSet和HashMap在判断两个元素是否相等时,会先判断hashCode,如果两个对象的hashCode不同则必定不相等。

以下是源码展示:在这里插入图片描述

2、HashSet保证元素的唯一性

代码演示:
有一个User类,只重写equals()方法,然后放到HashSet集合中去重

public class User {

    private String id;

    private String name;

    private Integer age;
    
    public User(String id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(id, user.id) &&
            Objects.equals(name, user.name) &&
            Objects.equals(age, user.age);
    }
    
    //此处省略getter、setter、toString方法
}

然后我们循环创建3个成员变量的值都是一样的User对象,最后放到Set集合中去重

public static void main(String[] args) {
    List<User> list = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
        User user = new User("1", "张三", 18);
        list.add(user);
    }
    Set<User> set = new HashSet<>(list);
    for (User user : set) {
        System.out.println(user);
    }
}

按道理我们预期会去重,只剩下一个“张三”的user,但实际上因为没有重写hashCode方法,所以没有去重。

运行结果
在这里插入图片描述
接着我们在User类里面重写一些hashCode方法再试试,其他不变

public class User {
    //其他不变
    
    //重写hashCode方法
    @Override
    public int hashCode() {
        return Objects.hash(id, name, age);
    }
}

运行结果

在这里插入图片描述

究其原因在于HashSet会先判断hashCode是否相等,如果hashCode不相等就直接认为两个对象不相等,不会再用equals()比较了。我们不妨看看重写hashCode方法和不重写hashCode方法的哈希码。

这是不重写hashCode方法的情况,每个user对象的哈希码都不一样,所以HashSet会认为都不相等。

在这里插入图片描述
在这里插入图片描述
那么有些人看到这里,就会问,如果两个对象返回的哈希码都是一样的话,是不是就一定相等?

答案是不一定的,因为HashSet、HashMap判断哈希码相等后还会再用equals()方法判断。

总结:
1.HashCode方法和equals方法都是Object类中的方法,即所有对象都有equals方法和HashCode方法;
2.两个对象通过equals比较是相等的,那么HashCode肯定相等;相反的,两个对象通过HashCode比较是相等的,那么equals不一定相等;
3.只要重写equals方法,就必须重写HashCode方法;

完!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HashCode()和equals()的区别 的相关文章

随机推荐

  • PHP调用C语言实现接口方法

    一 环境准备 环境 xff1a CentOS Linux release 7 3 1611 Core PHP 5 4 16 安装php 查看php版本 yum install php php devel php v 二 so 动态库封装 r
  • dd if=/dev/zero of=的含义是什么?Linux 下的dd命令使用详解

    xfeff xfeff dd if 61 dev zero of 61 的含义是什么 xff1f Linux 下的dd命令使用详解 转载 xff1a http blog sina com cn s blog 8b5bb24f01016y3o
  • mysql 错 Could not open JDBC Connection for transaction; nested exception is java.sql.SQLExceptio

    运行时报com mysql jdbc exceptions jdbc4 MySQLSyntaxErrorException Unknown character set 39 utf8mb4 39 导致 浏览器报Could not open
  • axios.create、拦截器、取消请求

    axios create config 根据指定配置创建一个新的 axios 也就就每个新 axios 都有自己的配置新 axios 只是没有取消请求和批量发请求的方法 其它所有语法都是一致的为什么要设计这个语法 1 需求 项目中有部分接口
  • 启明云端分享:产品应用上,怎么选型ESP-12F\ESP-12E\ESP-12S\ESP-07S这四个模块

    提示 xff1a ESP 12F ESP 12E ESP 12S ESP 07S四个模块怎么选型呢 前言 ESP 12F ESP 12E ESP 12S ESP 07S这四个模块采用的都是乐鑫ESP8266芯片封装的模块 其中ESP 12F
  • echarts图表分区域--显示不同颜色(markArea)

    项目需要这样的效果 xff0c 在y轴数值大于50的时候 xff0c 向上的区域显示不同的颜色 xff1a 查阅官方文档有一个属性markArea xff0c 是标记背景区域的 xff0c 官方是这样配置的 xff1a 因为我有多个色块 x
  • ChatGPT自我分析

    作者 xff1a chatgpt ChatGPT 是一个由 GPT 技术驱动的聊天机器人 xff0c 它能够回答各种问题 提供信息和建议 生成文本和完成其他任务 ChatGPT 是一个深度学习模型 xff0c 是人工智能技术中的一种 在本博
  • Visutal Studio2022 如何使用Github copilot

    visual studio 2019 升级最新版本的2019也并没有搜索到 xff0c 直接升级到visual studio 2022 xff0c 看发布介绍也是2022的copilot Copilot 是一款由 OpenAI 开发的基于
  • 音视频领域的经典书籍推荐

    数字视频处理基础 xff08 Digital Video Processing xff09 xff1a 作者A Murat Tekalp xff0c 讲述数字视频处理的基本概念和技术 xff0c 包括视频编码 图像分析 视频通信和多媒体系统
  • 音视频专家

    作为一名顶级的音视频专家 xff0c 需要在音视频领域拥有非常深入的技术理解和丰富的实践经验 xff0c 并且要能够在行业内产生深远的影响和贡献 以下是更详细的顶级音视频专家提升计划 xff1a 1 深入研究音视频核心技术 作为顶级音视频专
  • 2022年新兴技术趋势

    图片源自 xff1a 2022年Gartner新兴技术成熟度曲线公布最新技术趋势 Gartner中国 人工智能和机器学习技术仍处于高峰 xff0c 但已经开始进入成熟期 这表明人工智能和机器学习技术已经不再是新颖的概念 xff0c 而是逐渐
  • 白镜1-1

    2029年 xff0c 人类社会已经进入了全球化 数字化 智能化的新时代 xff0c 各国政府和企业已经开始在深海和太空等地方进行勘探和开采 同时 xff0c 在不断提升的科技水平下 xff0c 人类已经开始了向宇宙的探索和移民 在这样一个
  • Jetson查看GPU显存信息

    pip3 install jetson stats jtop 然后运行jtop命令即可 xff0c jetson xavier nx 的查看命令并不是nvidia smi xff0c 所以运行nvidia smi并没有效果 xff01 效果
  • 并不包含调试信息(未加载任何符号)

    今天调试一C 43 43 程序 xff0c 按下F5 xff0c 老是弹出一对话框显示信息 xff1a debugging information for 39 myproject exe 39 cannot be found or doe
  • hdu 1358 Period KMP

    题目大意 xff1a 对于一个字符串 xff0c 找由循环字符串组成的位置 xff0c 并输出最多循环了几次 xff0c 比如两个样例 xff0c 第一个是 aaa xff0c 所以在第二个位置由子串a循环两次得到 xff0c 第三个位置由
  • mysql max_connections 最大连接数,用户数

    设置max connections xff08 这个办法在debian xff0b mysql Ver 12 22 Distrib 4 0 22 for pc linux i386 里实验了 xff09 设置办法是在my cnf文件中 xf
  • dll文件加载运行加载的14001错误,由于应用程序配置不正确,应用程序未能启动

    最近在处理项目问题的的时候发现了这么一个问题 xff0c 就是我们的程序在调用第三方提供的dll文件的时候在一台机器上面会报14001的错误 xff0c 但是在另一台机器上面不会 两台机器上面的操作系统是相同的 针对这个问题和这个错误码 x
  • Python框架下django 的并发和多线程

    django 的并发能力真的是令人担忧 xff0c django本身框架下只有一个线程在处理请求 xff0c 任何一个请求阻塞 xff0c 就会影响另一个情感求的响应 xff0c 尤其是涉及到IO操作时 xff0c 基于框架下开发的视图的响
  • Linux查看电源状态指令

    dmidecode命令可以让你在Linux系统下获取有关硬件方面的信息 dmidecode的作用是将DMI数据库中的信息解码 xff0c 以可读的文本方式显示 由于DMI信息可以人为修改 xff0c 因此里面的信息不一定是系统准确的信息 d
  • HashCode()和equals()的区别

    文章目录 HashCode简介equals简介1 类中重写HashCode和equals方法比较两个对象是否相等2 HashSet保证元素的唯一性 HashCode简介 hashCode 方法的作用是获取哈希码 xff0c 返回的是一个in