规则

  1. 只要重写equals,就必须重写hashCode。

  2. 用Set存储对象或者用对象作为Map的键时,必须重写hashCode。也就是说,当需要用对象的哈希值来判断对象是否相等时必须重写hashCode。

    说明:String重写了hashCode和equals方法,所以我们可以非常愉快地使用String对象作为key来使用。

介绍

  1. Equals的作用是用来判断两个对象是否相等。
  2. hashCode 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数,这个哈希码的作用是确定该对象在哈希表中的索引关系。

关系(我们以“类的用途”来将“hashCode()和equals()的关系”分两种情况来说明)

  1. 不会创建“类对应的散列表”

    不会创建类对应的散列表是说:我们不会在HashSet, Hashtable, HashMap等等这些本质是散列表的数据结构中,用到该类。例如,不会创建该类的HashSet集合,不会以该类作为Map的键。在这种情况下,hashCode和 equals是没有关系的。而hashCode() 则根本没有任何作用。

    equals() 用来比较该类的两个对象是否相等,必要时还是需要重写。以下这种情况按照正常业务应该返回true,但是实际结果却是false。

    public static void main(String[] args) {
    Student student1 = new Student();
    student1.setName("张三");
    student1.setAge(1); Student student2 = new Student();
    student.setName("张三");
    student.setAge(1); System.out.println(student1.equals(student2));
    }

    重写equals我们就可以根据我们实际的情况来判断是否相等。

    @Override
    public boolean equals(Object o) {
    if (this == o) {
    return true;
    }
    if (o == null || getClass() != o.getClass()) {
    return false;
    }
    Student student = (Student) o;
    return age == student.age && Objects.equals(name, student.name);
    }

    这种情况下,hashCode没有实际意义

  2. 会创建类对应的散列表

    创建类对应的散列表是说:我们会在HashSet,Hashtable,HashMap等等这些本质是散列表的数据结构中,用到该类。在这种情况下,该类的“hashCode()和equals()”是有关系的:

    1. 如果两个对象相等,那么hashCode返回的值一定相等,通过equals比较两个对象也相等。
    2. 如果两个对象hashCode()相等,它们并不一定相等。因为在散列表中,hashCode相等,即两个键值对的哈希值相等。然而哈希值相等,不一定能得出键值对相等。补充说一句:“两个不同的键值对,哈希值相等”,这就是哈希冲突。

总结

以程序角度看图1中student1和student2必然是两个不同的对象,new对象的时候JVM分配的不通的内存。但是以业务和面向对象来看,student1和student2的所有属性都相同,我们必须把他们当成同一个对象来处理。需要比较的时候我们则需要重写equals来具体比较对象的属性值,用Set去重时我们也得重写hashCode来给这种相对的对象返回相等的哈希值。如果没有以上需求则不用重写hashCode和equals,这两者也没有关系。这是自己对重hashCode和equals的理解,因为自己技术菜理解比较片面。专业解释还请看 说说hashCode() 和 equals() 之间的关系

类对应的散列表

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

关于hashCode和equals重写的更多相关文章

  1. java equals重写

    @Override    public boolean equals(Object obj) {        if(this == obj) {            return true;   ...

  2. hashCode 和 equals 的区别

    今天记录一下hashCode的知识,以前都没有怎么接触过的,感觉还是很陌生,专门去学习了一下 首先我最大的问题就是hashCode究竟是干什么 的,现在也一知半解了吧, 哈希值是一个对象的地址值,是一 ...

  3. 用HashSet的add方法谈hashcode和equals方法重写

    本文主要通过用HashSet的add方法讲一下hashCode和equals方法重写.错误的地方望指正. 1.了解HashSet的add方法 了解一个方法的好办法是看源码,所以先看源码 private ...

  4. java集合框架(hashSet自定义元素是否相同,重写hashCode和equals方法)

    /*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不一致,元素不可以重复 * (通过哈希值来判断是否是同一个对象) * ----HashSet:底层数据结构是哈希表, * 保证 ...

  5. 为什么要重写 hashcode 和 equals 方法?

    引言 以前面试的时候被面试官问到过这样一个问题: 你有没有重写过 hashCode 方法? 心里想着我没事重写哪玩意干啥,能不写就不写.嘴上当然没敢这么说,只能略表遗憾的说抱歉,我没写过. 撇了面试官 ...

  6. 为什么要重写hashcode和equals方法?初级程序员在面试中很少能说清楚。

    我在面试 Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分, ...

  7. 【转】 如何重写hashCode()和equals()方法

    转自:http://blog.csdn.net/neosmith/article/details/17068365 hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它 ...

  8. java为什么要重写hashCode和equals方法?

    如果不被重写(原生)的hashCode和equals是什么样的? 不被重写(原生)的hashCode值是根据内存地址换算出来的一个值. 不被重写(原生)的equals方法是严格判断一个对象是否相等的方 ...

  9. 正确重写hashcode hashcode与equals方法 集合元素如何判断是否相等 集合如何查看是否包含某个元素

    首先记住两句话 相等的两个对象,即equals(Object)方法判断两个对象相等,那么他们必须要有相同的hashcode hashcode相同的两个对象,他们可能相同,也可能不相同 简单地说可以这么 ...

  10. 关于HashMap自定义key重写hashCode和equals的问题

     使用HashMap,如果key是自定义的类,就必须重写hashcode()和equals() hashcode()和equals()都继承于object,在Object类中的定义为: equals( ...

随机推荐

  1. Linux文件IO之一 [补档-2023-07-21]

    Linux文件IO 8-1C标准库IO函数的工作流程 ​ 使用fopen函数打开一个文件,之后会返回一个FILE* fp指针,fp指针指向一个结构体,这个结构体是c 标准io库中的一个结构体,这个结构 ...

  2. iOS 17.4 测试版包含大模型相关代码

    外界普遍预计苹果将在 6 月份通过 iOS 18 推出主要的新人工智能功能.不过根据 9to5Mac 的报道,他们在 iOS 17.4 第一个测试版中发现的代码表明,苹果正在开发由大语言模型技术支持的 ...

  3. 使用HttpServletResponse实现curl接口时控制台输出(续)

    上一篇文章的问题 在上一篇文章 Spring Boot RestController接口如何输出到终端 中讨论了如何使用 HttpSerlvetResponse 写入输出流,使应急接口通过 curl ...

  4. Codeforces Round #884 (Div. 1 + Div. 2) A-E

    比赛链接 A 代码 #include <bits/stdc++.h> using namespace std; using ll = long long; bool solve() { i ...

  5. 使用JS访问本地数据库

    1 前言 有时候,数据业务比较大,比如查询百万级的数据,如果使用JSP查询数据库,JSP的返回结果一般放在域名后面返回给客户端,而返回结果的长度是有限制的,数据过长可能会丢失部分数据:另一方面数据量大 ...

  6. 微信小程序获取本日、本周、本月、本年时间段

    原文链接 https://cslaoxu.vip/110.html 说明 最近需要用到统计不同时间段内的记录数,所以找了一下现成的工具类.下面就演示一下如何引用到实际项目中. 详细用法请参考:http ...

  7. fastjson反序列化各版本利用汇总

  8. 我在winform项目里使用“Windows I/O完成端口”的经验分享

    少年!看你骨骼惊奇,是万中无一的练武奇才,我这儿有本武林秘籍,见与你有缘就送你了! 如来神掌 Windows I/O完成端口是一个我至今都说不好的话题,请宽容的接受我这不是科班出身的自学成才的野生程序 ...

  9. 【学习笔记】 - 基础数据结构 :Link-Cut Tree

    发现树剖代码太长了,给我恶心坏了 学个代码短点的能写树剖题的数据结构吧 前置知识 平衡树splay 树链剖分 简介以及优缺点介绍 Link-Cut Tree,也就是LCT,一般用于解决动态树问题 Li ...

  10. [BUUCTF][Web][极客大挑战 2019]LoveSQL 1

    打开靶机url,页面显示有两个输入框,框中输入123',发现两个框都有sql注入问题 爆出一下错误 You have an error in your SQL syntax; check the ma ...