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

为什么重写equals必须重写hashCode

关于这个问题,看了网上很多答案,感觉都参差不齐,没有答到要点,这次就记录一下!

首先我们为什么要重写equals?这个方法是用来干嘛的?

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

 上面是在Object类里面的定义,可以看到它的作用仅仅是用来确认两个对象地址是否一样!

那实际当中我们肯定不满足于这个方式啊!我们一般是想知道两个对象里面的数据是否对的上!

最直接的例子就是String!这里官方给我们重写了equals方法,从而使得我们在进行比较不同的string的时候比较的不是它们的地址,而是字面值!!!具体源码大家可以自己去看。

我这里也定义了一个类,然后演示一下重定义equals前后的结果:

public class People {private String name;public People(String name){this.name=name;}public void setName(String name) {this.name = name;}public String getName() {return name;}public String toString(){return "Peopel"+"name:"+name;}}
public class a {public static void main(String[] args) {People hj=new People("wx");People nn=new People("wx");System.out.println(hj.equals(nn));}
}

 

这是测试主类,输出是false!(两个对象地址不一样,当时输出false,因为这个时候我们没有重写equals方法!!!) 但是实际当中我们当然期望是true!因为这里两个对象里面属性是完全一样。

那么我们重写一下,看看最后的结果!

public boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;People other = (People) obj;if (name != other.name)return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}

 上面是重写的方法,具体的话大家自己看,逻辑也很清楚!

这次我们实现了输出true(开心)

 --------------------------------------------------------------------------------------------------------------------------------至此我们搞懂了重写equals的目的!!

下面正式进入主题!hashcode!

首先定义一下hashcode:它是一个函数,将对象映射成一个整数

那么大家会说,这个函数是什么?

(165条消息) Java 的 HashCode 底层生成分析_董酷酷的博客-CSDN博客_hashcode底层

具体大家可以看这个链接,给大家总结一下哈,这个函数一般是伪随机数生成函数,和对象地址是无关的!(除非你指定编译器参数)

 那么我们为啥要重写这个函数呢?

让含有相同参数的对象 映射成相同的hashcode!!!(这句话很关键,我下面的阐述都是基于此展开的)

有人有会问为什么要映射成相同的hashcode呢?那我举个最简单的例子吧!

我现在有个hashmap,对象为k,v就是1

当你第一次 push一个对象(参数是a)后

第二次 push一个对象(参数也是a)

正常来说我们希望,后面的put操作会覆盖前面的

但如果你不重写hashcode就不会实现覆盖,map里会包含两个对象

这是因为hashmap put的原理是,首先判断对象的hashcode,如果不等,直接判断为不同的key,如果相等,则执行equals方法来看是否相同

下面是代码!

public class a {public static void main(String[] args) {HashMap<People,Integer> map=new HashMap();People cxk=new People("wx");map.put(cxk,1);People yyqx=new People("wx");map.put(yyqx,1);map.forEach((k,v)->{System.out.println(k);});}
}

这是测试类,最后结果是:

 那我们重写hashcode后:

 ok,实际上重写hashcode主要保证的是一致性:相同参数的对象映射到相同的hash值,从而保证我们在集合里面能够正确的实现。

http://www.lryc.cn/news/9941.html

相关文章:

  • < 每日小技巧:N个很棒的 Vue 开发技巧, 持续记录ing >
  • 数据结构与算法之二分查找分而治之思想
  • 训练自己的中文word2vec(词向量)--skip-gram方法
  • ubuntu系统环境配置和常用软件安装
  • 【1139. 最大的以 1 为边界的正方形】
  • windows11安装sqlserver2022报错
  • Python快速上手系列--日志模块--详解篇
  • 【THREE.JS学习(1)】绘制一个可以旋转、放缩的立方体
  • 数仓实战 - 滴滴出行
  • python虚拟环境与环境变量
  • BeautifulSoup文档4-详细方法 | 用什么方法对文档树进行搜索?
  • 初识Tkinter界面设计
  • 软件测试面试题中的sql题目你会做吗?
  • VS实用调试技巧
  • 通俗易懂理解三次握手、四次挥手(TCP)
  • 1.1 什么是并发
  • 万字讲解你写的代码是如何跑起来的?
  • 034.Solidity入门——21不可变量
  • Vulnhub 渗透练习(四)—— Acid
  • C++ 在线工具
  • 使用MMDetection进行目标检测、实例和全景分割
  • 使用ThreadLocal实现当前登录信息的存取
  • 高通平台开发系列讲解(Android篇)AudioTrack音频流数据传输
  • BUUCTF-firmware1
  • 【C++之容器篇】二叉搜索树的理论与使用
  • 爬虫神级解析工具之XPath:用法详解及实战
  • Markdown编辑器
  • 数据结构<堆>
  • Linux下Socket编程利用多进程实现一台服务器与多台客户端并发通信
  • 【MySQL】数据库基础