16 两个对象值相同(x.equals(y) == true),但却可以有不同的hashCode,这句话对不对?

不对,如果两个对象x和y满足x.equals(y) == true,那么他们的哈希码应该相同。

根据hashCode方法协定:在每个重写了equals方法的类中,必须重写hashCode方法,如果不这样做的话,就会导致该类无法与基于哈希表的集合一起使用。

接下来我们以HashSet为例说明:

HashSet基于HashMap实现,底层采用HashMap保存元素,元素无序、不重复。

当向HashSet添加元素a时,首先调用a所属类的hashCode方法,计算a的哈希值,接着利用hash值通过某种算法计算出元素在HashSet底层数组中的存放位置;

判断此位置上是否有元素:如果没有,则a添加成功;如果有,假设存在元素b,则先比较a和b的哈希值;

如果哈希值不同,则a添加成功;如果哈希值相同,则继续通过调用a所属类的equals方法比较;

如果返回true,a添加失败;如果返回false,a添加成功。

分析:

以上就是集合HashSet的简要说明及实现原理,假设我们新建一个类Student,重写了equals方法(只要name相等即为true),没有重写hashCode方法,当new了两个相同name的对象stu1,stu2后,分别添加到HashSet中,首先stu1经过hashCode方法,计算哈希值,然后找到自己在数组中的存放位置,发现没有元素,添加成功;接着stu2也调用hashCode方法,但是由于没有重写hashCode方法,返回了不同的哈希值,经过计算也找到了自己在数组中要存放的位置,且该位置和stu1的不同,也添加成功,这就发生了错误,因为我们知道HashSet是不可重复的集合。

结语:

当然,如果你的类根本就不会和基于哈希表的集合一起使用,如ArrayList,你也可以不重写hashCode方法,但是,这就像是Java的一种约定,我们最好遵守它。

Original: https://www.cnblogs.com/xilichenbokeyuan/p/14167555.html
Author: 卫盾
Title: 16 两个对象值相同(x.equals(y) == true),但却可以有不同的hashCode,这句话对不对?

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/576013/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 滑动窗口

    滑动窗口,记录左边界,通过map避免字符重复。 class Solution { public int lengthOfLongestSubstring(String s) { i…

    数据库 2023年6月11日
    068
  • 网卡限速工具之WonderShaper

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。 GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。 什么是WonderShaper …

    数据库 2023年5月24日
    081
  • break&continue&return

    作用 1. 跳出整个循环体,进入循环下面的语句 2. 在多层嵌套循环中,break跳出内层循环 3. 可以使用带标签的break语句,跳出外层循环 编码 //break终止循环 p…

    数据库 2023年6月14日
    090
  • ShardingSphere-JDBC进行分库分表

    一、前言:分库分表 在大型的互联网系统中,可能单台MySQL的存储容量无法满足业务的需求,这时候就需要进行扩容了。 和之前的问题一样,单台主机的硬件资源是存在瓶颈的,不可能无限制地…

    数据库 2023年6月14日
    067
  • 类的加载流程

    概述 什么是类加载呢? 我们知道一个Class文件编译完成之后是存在于磁盘的一个普通文件,如果想要执行,必然需要将 Class文件加载到…

    数据库 2023年6月11日
    068
  • Qt 圆角头像的实现

    在QT 中设置圆形头像,本文记录了两个解决思路。 将头像显示在QLabel 此类控件中,设置QLabel 为一个正方形,接着设置QLabel 的圆角属性,可以实现圆形头像的效果。 …

    数据库 2023年6月16日
    095
  • Redisson

    ​ Redisson是架设在Redis基础上的一个Java驻内存数据网格(In-Memory Data Grid)。充分的利用了Redis键值数据库提供的一系列优势,基于Java实…

    数据库 2023年6月6日
    084
  • mysql拆分字符串做条件查询

    mysql拆分字符串作为查询条件 有个群友问一个问题 这表的ancestors列存放的是所有的祖先节点,以 ,分隔 例如我查询dept_id为103的所有祖先节点,现在我只有一个d…

    数据库 2023年5月24日
    069
  • MySQL 的日志:binlog

    前言:binlog 用于记录数据库执行 写入性操作的日志信息,以二进制的形式保留在磁盘中。它是由 Server 层进行记录的,使用任何存储引擎都会产生 binlog。 实验准备 我…

    数据库 2023年5月24日
    082
  • Xtrabackup 8.0.x关于MySQL的版本支持的浅析

    我们知道从MySQL 8.0.x开始,我们必须用Percona Xtrabackup 8.0.x来备份,之前的Percona XtraBackup 2.4已经不支持MySQL 8….

    数据库 2023年5月24日
    0140
  • 绿色安装MySQL5.7版本—-配置my.ini文件注意事项

    简述绿色安装MySQL5.7版本以及配置my.ini文件注意事项 前言 由于前段时间电脑重装,虽然很多软件不在C盘,但是由于很多注册表以及关联文件被删除,很多软件还需要重新配置甚至…

    数据库 2023年5月24日
    089
  • Dubbo源码(三)-服务导出(生产者)

    前言 本文基于Dubbo2.6.x版本,中文注释版源码已上传github:xiaoguyu/dubbo 在了解了Dubbo SPI后,我们来了解下Dubbo服务导出的过程。 Dub…

    数据库 2023年6月11日
    081
  • 接口和抽象类有什么区别

    1.抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象 2.抽象类要被子类继承,接口要被类实现 3….

    数据库 2023年6月6日
    061
  • 如何成为一名开发人员——第 1 部分:编码技巧

    1 学习一门语言 程序员编写计算机代码,所以你必须学会说这种语言。 但是, 你首先学习哪种编程语言并不重要!这完全取决于你对什么感兴趣。例如… 如果你想进入 Web 开…

    数据库 2023年6月14日
    090
  • SpringBoot操作Oracle

    /* Navicat Premium Data Transfer Source Server : 本地Oracle Source Server Type : Oracle Sour…

    数据库 2023年6月14日
    088
  • MySQL45讲之InnoDB加锁规则

    前言 本文介绍 MySQL InnoDB 的加锁规则,以及一些需要注意的点。 总结 可重复读隔离级别下,两个原则,两个优化,一个 bug: 原则1:加锁的基本单位是 next-ke…

    数据库 2023年5月24日
    072
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球