微信搜索「码农田小齐」,关注这个在纽约的程序媛,回复「01-05」可以获取计算机精选书籍、个人刷题笔记、大厂面经、面试资料等资源,么么哒~

首先我们有一个假设:任何两个 object 的 hashCode 都是不同的。

那么在这个条件下,有两个 object 是相等的,那如果不重写 hashCode(),算出来的哈希值都不一样,就会去到不同的 buckets 了,就迷失在茫茫人海中了,再也无法相认,就和 equals() 条件矛盾了,证毕。

撒花~~

接下来我们再对这两个方法一探究竟:

其实 hashCode() 和 equals() 方法都是在 Object class 这个老祖宗里定义的,Object 是所有 Java 中的 class 的鼻祖,默认都是有的,甩不掉的。

那既然是白给的,我们先来看看大礼包里有什么,谷歌 Object 的 Oracle 文档:

所以这些方法都是可以直接拿来用的呢~

回到 hashCode() 和 equals(),那么如果这个新的 class 里没有重写 (override) 这两个方法,就是默认继承 Object class 里的定义了。

那我们点进去来看看 equals() 是怎么定义的:

记笔记:

equals() 方法就是比较这两个 references 是否指向了同一个 object.

嗯???你在逗我吗??那岂不是和 == 一样了??

补充:

我们常用的比较大小的符号之 ==

如果是 primitive type,那么 == 就是比较数值的大小;

如果是 reference type,那么就比较的是这两个 reference 是否指向了同一个 object。

再补充:

Java 的数据类型可以分为两种:

Primitive type 有且仅有8种:byte, short, int, long, float, double, char, boolean.

其他都是 Reference type.

所以虽然 Java 声称 “Everything is object”,但是还是有非 object 数据类型的存在的。

我不信,我要去源码里看看它是怎么实现的。

哈,还真是的,绕了这么半天,equals() 就是用 == 来实现的!

那为什么还弄出来这么个方法呢?

答:为了让你 override~

比如一般来说我们比较字符串就是想比较这两个字符串的内容的,那么:

str1 = “tianxiaoqi”;
str2 =  new String(“tianxiaoqi”);

str1 == str2; // return false
str1.equals(str2); // return true 

因为 String 里是重写了 equals() 方法的:

老祖宗留给你就是让你自己用的,如果你不用,那人家也提供了默认的方法,也是够意思了。

好了,我们再去看 hashCode() 的介绍:

那至于 hashCode() 返回的究竟是什么,和本文关联不太大,有兴趣的同学可以看参考这篇文章[1],结论就是:

返回的并不一定是对象的(虚拟)内存地址,具体取决于运行时库和JVM的具体实现。

但无论是怎么实现的,都需要遵循文档上的约定,也就是对不同的 object 会返回唯一的哈希值

所以说,

hashCode() 决定了 key 放在这个桶里的编号,也就是在数组里的 index;

equals() 是用来比较两个 object 是否相同的。

如果你喜欢这篇文章,记得给我点赞留言哦~你们的支持和认可,就是我创作的最大动力,我们下篇文章见!

我是小齐,纽约程序媛,终生学习者,每天晚上 9 点,云自习室里不见不散!

更多干货文章见我的 Github: https://github.com/xiaoqi6666/NYCSDE

参考资料

[1]

hashCode()参考文章: https://blog.csdn.net/xusiwei1236/article/details/45152201

为什么重写 equals() 方法,一定要重写 hashCode() 呢?| HashMap的更多相关文章

  1. 为什么重写equals()方法就必须重写hashCode()方法

    hashCode()和equals()保持一致,如果equals方法返回true,那么两个对象的hasCode()返回值必须一样.如果equals方法返回false,hashcode可以不一样,但是这 ...

  2. 一文搞懂--Java中重写equals方法为什么要重写hashcode方法?

    Java中重写equals方法为什么要重写hashcode方法? 直接看下面的例子: 首先我们只重写equals()方法 public class Test { public static void ...

  3. 重写equals()方法也要重写hashcode()方法

    如果我们对equals方法进行了重写,建议一定要对hashCode方法重写,以保证相同的对象返回相同的hash值,不同的对象返回不同的hash值.

  4. JAVA中重写equals()方法为什么要重写hashcode()方法?

    object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true:注意:当此方法 ...

  5. JAVA中重写equals()方法为什么要重写hashcode()方法说明

    重写hashCode()时最重要的原因就是:无论何时,对同一个对象调用hashCode()都应该生成同样的值.如果在将一个对象用put()方法添加进HashMap时产生一个hashCode()值,而用 ...

  6. 为什么重写equals方法还要重写hashcode方法?

    我们都知道Java语言是完全面向对象的,在java中,所有的对象都是继承于Object类.Ojbect类中有两个方法equals.hashCode,这两个方法都是用来比较两个对象是否相等的. 在未重写 ...

  7. 为什么要重写equals()方法与hashCode()方法

    在java中,所有的对象都是继承于Object类.Ojbect类中有两个方法equals.hashCode,这两个方法都是用来比较两个对象是否相等的. 在未重写equals方法我们是继承了object ...

  8. 为什么重写 equals 方法 必须重写 hashCode

    自己学到这,就记录了下来,代码都是自己敲得,有不对的地方希望大神指点出来 为什么重写 equals 方法 必须重写 hashCode 如果你重写了equals,比如说是基于对象的内容实现的,而不重写 ...

  9. Java中equals和==的区别?为什么重写equals方法后,一定要重写hashCode方法?

    首先明确一点,equals是方法,==是操作符. 1. 如果比较的是基本数据类型: 只讨论==,因为equals是不存在的,因为java中基本数据类型不能调用method的. 2. 如果比较的是引用类 ...

  10. 重写equals方法,也应该重写hashcode方法,反之亦然

    yls 2019年11月07日 一方面 hashcode原则:两个对象equals相等,hashcode值一定相等 默认的hashcode是Object类通过对象的内存地址得到的 若重写equals而 ...

随机推荐

  1. Jmeter之『JSR223脚本』

    Json处理(通过JS) 对于Json字符串,需要使用单引号『''』(因为Json中已存在双引号) // String转为Object var jsonObj = JSON.parse('${data ...

  2. Python数据类型---数值类型

    一.整数(Integer)简称Int,又称整型,由正整数.负整数.0构成,不包括小数,分数. a,b=1,2 #一种赋值方法,此时a=1,b=2 print(a+b) #加法 3 print(a-b) ...

  3. jvm堆内存和GC简介

    最近经常遇到jvm内存问题,觉得还是有必要整理下jvm内存的相关逻辑,这里只描述jvm堆内存,对外内存暂不阐述. jvm内存简图 jvm内存分为堆内存和非堆内存,堆内存分为年轻代.老年代,非堆内存里只 ...

  4. day44 Pyhton 数据库Mysql

    内容回顾 什么是进程? 就是为了形容执行中的程序的一种称呼 它是操作系统中资源分配的最小单位 进程之间是数据隔离的,占用操作系统资源相对多 独立存在的 谈谈你对并发的理解 同时有多个任务需要执行,但是 ...

  5. Android ContentProvider 基本原理和使用详解

    ContentProvider(内容提供者)是 Android 的四大组件之一,管理 Android 以结构化方式存放的数据,以相对安全的方式封装数据(表)并且提供简易的处理机制和统一的访问接口供其他 ...

  6. logstash 过滤filter

    logstash过滤器插件filter详解及实例   1.logstash过滤器插件filter 1.1.grok正则捕获 grok是一个十分强大的logstash filter插件,他可以通过正则解 ...

  7. php闭包作为函数参数

    <?php function test(Closure $call) { $a = 63; $b = 22; echo "hello"; echo $call($a,$b); ...

  8. spring boot:使用caffeine+redis做二级缓存(spring boot 2.3.1)

    一,为什么要使用二级缓存? 我们通常会使用caffeine做本地缓存(或者叫做进程内缓存), 它的优点是速度快,操作方便,缺点是不方便管理,不方便扩展 而通常会使用redis作为分布式缓存, 它的优点 ...

  9. C# URL编码

    #region URL编码 /// <summary> /// URL编码 /// </summary> /// <param name="str"& ...

  10. frida框架hook常用字符串模板总结

    ArrayBuffer转String: 解决中文乱码(模板) function ab2str(buf) { return new Uint16Array(buf) // encodedString = ...