【HashMap】为什么用自定义的类做HashMap的Key时需要重写hashcode方法和equals方法

news2024/11/29 20:30:07

【HashMap】为什么用自定义的类做HashMap的Key时需要重写hashcode方法和equals方法

  • 【一】为什么有这个问题
  • 【二】Object类的中的hashcode方法和equals方法
  • 【三】重写hashcode
  • 【四】重写equals方法
  • 【五】hashmap中使用hashcode和equals方法

【一】为什么有这个问题

因为HashMap的key有个特征,就是key值不能重复,否则add的时候会覆盖。那么如果使用自定义的类做HashMap的key,就需要用到equals方法判断两个对象是否相等,判断的条件就是hashCode生成的哈希值。

Java中所有的类都是Object类的子类,所以自定义的类也是Object类的子类,Object中自带的hashcode方法和equals方法,如果不重写hashcode方法和equals方法,即使两个自定义类的对象内容完全相同,也不会判定为重复,这也就违背了HashMap的key不可重复的特点。

【二】Object类的中的hashcode方法和equals方法

Java中所有的类都是Object类的子类,Object中自带的hashcode方法,就是通过计算内存地址转换一个整数实现的,是一个native方法,返回值是int类型:

public native int hashCode();

Object中自带的equals方法,从源码中可以看出,就是将比较与被比较对象用==进行比较,用的还是比较hash值的方式

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

【三】重写hashcode

如果不重写hashcode方法,那么即便是两个内容完全相同key对象,每次通过hashcode方法计算出的hash值也都是不一样的,因为是根据其对象所在内存地址计算的,因而做存储时也会被当作时不同的key;

重写hashcode方法该怎么写呢,这没有固定的格式,项目中看到很多中写法,列举两个

(1)如果是一个实体类,有唯一的字段id,那么可以利用该字段直接作为其hash值,如下

public class user{
    private int id;
    private String name;
    
    @override
    public int hashcode(){
        return this.id;
    }
}

(2)也可以是如下写法,因为String类中已经重写了hashcode方法,所以当name值相同时,其对应hash值一定相同

public class User{
    private int id;
    private String name;
    
    @override
    public int hashcode(){
        return id*name.hashcode;
    }
}

【四】重写equals方法

equals方法在上面已经介绍过了,其实就是用==进行比较,如果不重写那么即便是两个内容完全相同的对象,equals方法返回值依然是false,和hashcode类似也需要进行类似的方法重写:

(1)思路是先使用instanceof关键字判断这个被比较对象与对象是否属于一个类,返回值是true的话,再将二者转换成json字符串,最后通过String已经重写好了的equals方法进行比较,如下:

public class User{
    private int id;
    private String name;
    
    @override
    public boolean equals(Object object){
        if(object instanceof User){
            User compareObj = (User)object;
            String soureStr = JsonUtils.objectToJson(this);
            String targetStr = JsonUtils.objectToJson(compareObj);
            return soureStr.equals(targetStr);
        }
        return false;
    }
}

【五】hashmap中使用hashcode和equals方法

举例,将一个对象user对象作为key存入hashmap当中,会经历以下流程,能够看出在判断两个对象是否相等时,要经过以下步骤:

(1)是先去判断二者的hash值是否相同,因为计算和比较hash值所耗费代价要远低于通过equals进行比较,所以先比较hash值也可以提高效率;
(2)如果比较结果不相等,则直接返回false;
(3)如果比较结果相等,则使用equals方法进行比较;
(4)如果相等,则返回true,如果不相等,则返回fasle。

在这里插入图片描述

总结:在hashmap中,对于两个对象的比较,都充分用到了key对象的hashcode方法和equals方法;

如果不重写hashcode方法,那么即便是两个内容完全一致的key对象,它仍会视为是不同的key,导致数据存取无法进行;

如果不重写equals方法,那么equals方法只是简单的将两个对象进行==比较,实际上也是通过对象间的内存地址进行比较,也导致上述情况的发生。

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

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

相关文章

致我们那年青春热血的高考

#2023高考季# 本来试着去网上查一下当年的高考成绩,无奈查询密码实在想不起来,只能作罢。 2009年,我参加了高考。在这场考试中,我经历了各种复杂的情绪,紧张、焦虑、兴奋和期待,犹如坐过山车一样刺激。 我每…

实验篇(7.2) 05. 通过浏览器访问远端内网服务器 (FortiClient-SSL) ❀ 远程访问

【简介】直接将内网服务器映射成公网IP,可以方便的从任何地方访问服务器的指定端口,但是这种方式下,服务器是公开且暴露的。那有没有即方便、又比较安全的远程访问服务器的方法呢?我们来看看SSL VPN的Web模式。 SSL VPN介绍 从概念…

Linux 高级IO

目录 传统艺能😎概念😍高级IO😂五种 IO 模型👌阻塞 IO🙌非阻塞 IO😍信号驱动IO😊多路转接IO😂 异步IO😘同步通信 VS 异步通信😁同步通信 VS 同步与互斥&#…

Java006——对第一个Java程序HelloWorld的简单认识

一、HelloWorld.java程序整体认识 public class HelloWorld { //创建一个名字叫HelloWorld的类(Java中的类叫class)public static void main(String[] args) {//主程序入口,类似C语言main函数System.out.println("He…

黑客第一步:从认识这些DOS命令开始

文章目录 一、DOS是个啥?二、如何启动DOS命令行?1. 同时按下键盘winR键,打开运行框2. 在运行框输入命令cmd,然后点击确定,即可进入DOS命令行 三、常用的DOS命令 一、DOS是个啥? DOS(Disk Opera…

《精通特征工程》学习笔记(5):数据(特征)降维

1.数据降维 通过自动数据收集和特征生成技术,可以快速获取大量特征,但不是所有特征都是有用的。数据降维就是在保留重要信息的同时消除那些“无信息量的信息”。 “无信息量”有多种定义方法,PCA 关注的是线性相关性,假设我们将…

正态(高斯)分布什么时候等于杨辉三角(二项式)展开

(ab)^10的杨辉三角展开项系数是1,10,45,120,200,252,200,120,45,10,1 这些系数11项的和等于1004,每项除以1004&#xff0c…

数据结构与算法之美 | 递归(Recursion)

什么叫做递归? 递归:去的过程叫“递”,回来的过程叫“归” 递归的三个条件 条件一:一个问题的解可以分解为几个子问题的解 条件二:这个问题与分解之后的子问题,除了数据规模不同,求解思路完全…

CnOpenData全国养老机构数据

一、数据简介 养老机构指为老年人提供集中居住和照料服务的机构,县级以上地方人民政府民政部门负责本行政区域内养老机构的指导、监督和管理。其他有关部门依照职责分工对养老机构实施监督。 与其他服务不同的是,养老服务是一种全人、全员、全程服务,养老…

路径之谜 2016年国赛 深度优先搜索

目录 解题思路 AC代码: 题目描述 小明冒充 XX 星球的骑士,进入了一个奇怪的城堡。 城堡里边什么都没有,只有方形石头铺成的地面。 假设城堡地面是 nn 个方格。如下图所示。 按习俗,骑士要从西北角走到东南角。可以横向或纵向…

智能 CAN 总线/串口 RS-232485 协议转换器

能CAN/串口协议转换器LCNET Pro RS-232/485提供一路RS-485、一路RS-232和一路CAN通道,实现CAN与串口RS-485或RS-232之间的双向数据智能转换。每个通道独立隔离,每路通道采用金升阳电源模块和信号隔离芯片实现2500VDC电气隔离,电源输入防反设计…

NAT模式 LVS负载均衡群集部署

NAT模式 LVS负载均衡群集部署 一.部署共享存储(NFS服务器:192.168.80.102)1.关闭防火墙,查看是否有rpcbind和nfs-utils的包2.创建两个共享文件目录3.将共享路径及网段添加到/etc/exports中(设置为只可读)4.…

VulnHub项目:MONEYHEIST: CATCH US IF YOU CAN

靶机名称: MONEYHEIST: CATCH US IF YOU CAN 地址:MoneyHeist: Catch Us If You Can ~ VulnHub 这个系列是一部剧改编,还是挺好看的,大家有兴趣可以去看看! 废话不多说,直接上图开始! 渗透…

(单调栈) 496. 下一个更大元素 I——【Leetcode每日一题】

❓496. 下一个更大元素 I 难度:简单 nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。 给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中 nums1 是 nums2 的子集。 对…

直播美颜技术:视频美颜sdk的快速集成与开发实践

视频美颜sdk则是直播美颜技术的重要组成部分,它可以帮助开发者快速集成美颜功能,实现直播美颜。目前已经被广大平台、主播、平台用户所应用,在近几年甚至成了一个极其热门的讨论话题,毕竟它与人们的日常拍摄生活息息相关。 一、视…

重磅:百亿人工心脏赛道再添新玩家,行业未来趋势明显

市场火热,资本加持 昨日,深圳核心医疗科技股份有限公司自主研发的Corheart 6植入式左心室辅助系统获得国家药品监督管理局批准上市。这是一枚完全国产,拥有完备自主知识产权的人工心脏。该产品正式获批上市,加之之前获批的永仁心…

C++ 参数的三种传递方式和应用参加

C 参数的三种传递方式分别是值传递、指针传递和引用传递。 值传递 值传递的实质 将实参的值(a、b)复制到形参(m、n)相应的存储单元中,即形参和实参分别占用不同的存储单元。 值传递的特点 值传递的特点是单向传递,即主调函数…

「C/C++」C/C++ 回调函数

✨博客主页:何曾参静谧的博客 📌文章专栏:「C/C」C/C程序设计 相关术语 回调函数:是一种常用的编程技术,它可以将一个函数作为参数传递给另一个函数,并在后者执行过程中调用前者。回调函数通常用来处理异步…

python怎么搭建免费代理IP池,免费代理IP适合爬虫工作吗

Python可以使用一些第三方库和工具来搭建免费代理IP池。简单来说,搭建代理IP池的步骤如下: 1. 获取代理IP:从一些免费或付费代理IP网站上爬取并验证IP地址和端口信息。 2. 验证代理IP:使用代理IP访问一些网站或服务,验…

什么是IT服务请求管理

什么是服务请求 用户每天都会提出各种 IT 请求。它可能是对新软件的请求、旧硬件的更换、对应用程序的访问或资产组件的更改。这些请求被归类为服务请求。 服务请求是向 IT 团队发出的请求,以满足最终用户的需求。理想情况下,请求是从服务请求目录中选择…