规则

  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. 14.2 Socket 反向远程命令行

    在本节,我们将继续深入探讨套接字通信技术,并介绍一种常见的用法,实现反向远程命令执行功能.对于安全从业者而言,经常需要在远程主机上执行命令并获取执行结果.本节将介绍如何利用 _popen() 函数来启 ...

  2. 错误:基于tensorflow识别mnist数据集出现ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[10000,32,28,28] and type float on

    错误:最近,在尝试运行我以前博客代码的时候出现了如下错误 2020-04-03 10:53:22.982491: W tensorflow/core/common_runtime/bfc_alloca ...

  3. npm i -D和-s及-g以及--save的那些事

      i 是 install 的简写 -S 就是 --save 的简写 -D 就是 --save-dev 的简写 npm i module_name -S = > npm install modu ...

  4. .NET 云原生架构师训练营(模块二 基础巩固 REST && RESTful)--学习笔记

    2.3.1 Web API -- REST && RESTful 什么是 REST,什么是 RESTful RESTful API 设计 RESTful 成熟度模型 什么是 REST, ...

  5. .NET Core 在 K8S 上的开发实践--学习笔记

    摘要 本主题受众是架构师,开发人员,互联网企业 IT 运维人员.大纲:1. K8S 对应用的要求:2. .NET Core 上 K8S 的优势:3. K8S 下的 .NET Core 配置:4. .N ...

  6. 五一不休息,每天都学习,从零教你手写节流throttle

    壹 ❀ 引 我在 从零教你手写实现一个防抖debounce方法 一文中详细的介绍了防抖概念,以及如何手写一个防抖.既然聊到防抖那自然避不开同等重要的节流throttle,老规矩,我们先阐述节流的概念, ...

  7. JS Leetcode 503. 下一个更大元素 II 题解分析,依旧单调栈做法解决此题

    壹 ❀ 引 我在JS Leetcode 496. 下一个更大元素 I 更清晰的图解单调栈做法一文中,介绍了单调栈做法解决下一个更大元素的问题,比较巧的是这道题还有升级版,题目来自Leetcode503 ...

  8. Laravel入坑指南(11)——列队

    很高兴,我们来到了Laravel入坑指南的第11篇.这一系列的文章已经接近尾声了,在这一节里面,我们一起讨论列队的用法. 列队,顾名思义,将需要处理的任务一个一个排好队,等待处理程序来处理.这机的列队 ...

  9. Oracle日期格式化问题:to_date(sysdate,'yyyy-MM-dd')与 to_date(to_char(sysdate,'yyyy-MM-dd'),'yyyy-MM-dd')区别

    1.需求描述 对系统日期进行格式化,并仍保持日期类型 2.错误方法 直接使用to_date()实现 SELECT TO_DATE(SYSDATE,'YYYY-MM-DD') FROM DUAL; 这样 ...

  10. 第一百零四篇:DOM事件流

    好家伙,JS基础接着学,   1.事件流 页面哪个部分拥有特定的事件? 可以把页面想象成一个同心圆, 当你戳了其中的一点,其实你同时戳中了很多个圆   当你点击一个页面中的按钮,实际上你同时点击了这个 ...