首页 > 其他分享 >浅谈 equals() 和 hashCode()

浅谈 equals() 和 hashCode()

时间:2023-03-18 18:44:45浏览次数:48  
标签:相等 return 浅谈 equals hashCode 哈希 obj

equals()hashCode()Object 类中定义

  1. hashCode():用于计算对象哈希值。
  2. equals():用于比较对象是否相等。

默认实现

Object 定义的方法

默认实现:均基于对象引用地址

  1. equals():比较对象引用地址。

  2. hashCode():返回对象引用地址(本地方法)。

    public boolean equals(Object obj) {
        return (this == obj);
    }
    
    public native int hashCode();
    

方法重写

① 原因

为什么要重写

  1. 哈希集合的检索机制中,使用了 hashCode()equals()
  2. 在默认实现下,只有同一个对象引用的 equals()hashCode() 才会相等
  3. 在实际业务中,通常认为两个对象属性相同则对象相等。
  4. 需要成对重写 hashCode()equals(),才能实现对象的区分性。

示例

HashMap<User> userMap = new HashMap<>;
User u1 = new User("secret", 20);
User u2 = new User("secret", 20);
userMap.put(u1, "user1");

userMap.get(u2);	// 能获取到吗?
  • 未重写的情况:不能。因为 u1 和 u2 是不同的对象引用,hashcode()equals() 比较不相等。
  • 重写的情况:能。因为自定义了 hashCode() 计算规则、equals() 比较条件,u1 和 u2 视为相等的对象。

② 重写 equals()

通常认为:对象的属性值完全相同,则对象相等。

  1. 参数检查

    • 相同引用
    • 判空
    • 判类型
      • getClass()(严格):返回运行时具体类型,不考虑继承关系。
      • instanceOf(宽松):测试对象是否为类的实例(或接口实现类)。
  2. 比较属性:先向下转型,再比较属性值。

    1. 基本类型:使用 ==

    2. 引用类型:使用 Objects.equals() 方法,避免 NPE

      @Override
      public boolean equals(Object obj) {
          if (this == obj) {
              return true;
          }
      
          // 若严格要求类型一致,条件二改成 this.getClass() != obj.getClass()
          if (obj == null || !obj instanceof Person) {
              return false;
          }
          
          Person p = (Person) obj;
          
          // 不使用 xxx.equals(xxx),避免NPE
          return Objects.equals(this.name, p.name)
              && this.age == p.age;
      
      }
      

③ 重写 hashCode()

原则:尽量避免哈希冲突。

此处使用 Objects 工具类的方法。

@Override
public int hashCode() {
    return Objects.hash(name, age);
}

分析Objectshash(...)

  1. Objects.hash(...)

    1. 可变参数(数组)

    2. 调用 Arrays.hashCode(...) 计算哈希值。

      public static int hash(Object... values) {
          return Arrays.hashCode(values);
      }
      
  2. Arrays.hashCode(...):哈希算法 hash = 31 * hash + hash(i)

    1. 基于多个属性计算。

    2. 基于迭代的方式计算。

      public static int hashCode(Object a[]) {
          if (a == null)
              return 0;
      
          int result = 1;
      
          for (Object element : a)
              result = 31 * result + (element == null ? 0 : element.hashCode());
      
          return result;
      }
      

思考

选用 31 作为乘子的好处

  1. 质数:在计算时可以尽量减少哈希冲突。
  2. 性能优化
    1. 代码运行频繁时,JVM 会将 31 * i 优化为位运算 (i<<5) - 1
    2. 位运算的执行效率高。

方法成对重写后,equals()hashCode() 的关系

结论

  1. equals()hashCode() 都相等,才认为对象相同。

  2. equals() 相等,则 hashCode() 相等。

    描述 成立?
    逆命题 hashCode() 相等,则 equals() 相等 ❌(哈希冲突)
    否命题 equals() 不相等,则 hashCode() 不相等 ❌(哈希冲突)
    逆否命题 hashCode 不相等,则 equals() 不相等

标签:相等,return,浅谈,equals,hashCode,哈希,obj
From: https://www.cnblogs.com/secretmrj/p/17231466.html

相关文章

  • 浅谈DWS函数出参方式
    摘要:DWS的PL/pgSQL函数/存储过程中有一个特殊的语法PERFORM语法,用于执行语句但是丢弃执行结果的场景,常用于一些状态判断的场景。本文分享自华为云社区《GassDB(DWS)功能-......
  • “==” 与 equals 区别 简化易懂版
    首先,我们只需要看Object中的equals方法写的是啥 很显然,就是一句话,“==”与equals方法作用完全一致。都是用来比较在内存的首地址,即用来比较两个引用变量是否指向同......
  • 8年测试工程师,3年功能,5年自动化,浅谈我的自动化测试进阶之路...
     前言大家好我是小濠,本命马玉濠,已近从事测试行业8年了,自己也从事过3年的手工测试,从事期间越来越觉得如果一直在手工测试的道路上前进,并不会有很大的发展,所以通......
  • 浅谈Linux下的shell--BASH
    shell的概念与作用我们已经学习并知道了操作系统实际上就是一款软件,一款用来管理计算机软硬件资源,为用户提供良好的执行环境的软件。假如该软件能被用户随意操作,就会有可能......
  • 浅谈容量测试与容量规划
    转载:https://www.cnblogs.com/imyalost/p/9630846.html在性能测试中,需要根据具体的性能需求和系统架构等情况,采用不同的测试策略,其中最常见的策略就有容量测试。这篇博客......
  • 浅谈基准测试
    转载:https://www.cnblogs.com/imyalost/p/9630843.html之前的博客介绍过关于性能测试类型的内容,在性能测试中有一种测试类型叫做基准测试。这篇博客,就聊聊关于基准测试的......
  • ==和equals的区别
    一、八大基本数据类型和引用类型1.1八大基本数据类型1.整数类型:byte、short、int、long2.小数类型:float、double3.字符类型:char4.布尔类型:boolean1.2引用类型类、......
  • 珠海MES厂商浅谈实施MES系统的重要因素~
    执行好MES系统,是生产制造企业成功应用MES系统的前提,同时也是生产制造企业实现数字化、智能化工厂车间建设的的第一步,对于制造企业的未来的发展至关重要,那么如何执行好MES系......
  • [GO语言tips05]浅谈GORM常用方法
    0.引言GORM就是通过Go语言直接使用封装好的SQL语句,在使用的时候很多方法,那到底这些东西是如何执行的。主要说一下常见的几个CRUD方法。1.连接数据库使用的是gorm.Open......
  • 浅谈泰勒展开
    什么是导数对于一个一次函数\(\mathrm{f(x)=kx+b}\)来说,我们发现\(\mathrm{x}\)每增加一个单位长度,\(\mathrm{f(x)}\)都会相应的增加\(\mathrm{k}\)个单位长度......