Java 中记录与类的 hashCode() 和 equals() 的默认实现

2024-04-11

尝试使用示例代码来检查默认行为equals() and hashCode() for record vs class,但它的行为似乎有所不同record相比于class.

这是代码示例record and class

public class EqualsAndHashcode {
    public static void main(String[] args) {
        var employeeA = new Employee(101);
        var employeeB = new Employee(101);
        var employeeAClass = new EmployeeClass(102);
        var employeeBClass = new EmployeeClass(102);
        var printStream = System.out;
        printStream.println("record equals: " + employeeA.equals(employeeB) + "\nhashcode objA: " + employeeA.hashCode() + "\nhashcode objB: " + employeeB.hashCode());
        printStream.println("\nclass equals: " + employeeAClass.equals(employeeBClass) + "\nhashcode objA: " + employeeAClass.hashCode() + "\nhashcode objB: " + employeeBClass.hashCode());
    }
}

record Employee(int empId) {
}

class EmployeeClass {
    int empId;

    EmployeeClass(int empId) {
        this.empId = empId;
    }
}

上述代码执行后输出为:

record equals: true
hashcode objA: 101
hashcode objB: 101

class equals: false
hashcode objA: 935044096
hashcode objB: 396180261

任何人都可以帮助我了解记录的默认实现方式equals and hashCode与上面的行为不同?

如果有变化equals and hashCode实施记录,然后请帮助我了解该更改的确切目的是什么以及在哪些场景下使用它会更有帮助。


简而言之,区别很简单:

  • 默认实现equals() and hashCode() for java.lang.Object永远不会将两个对象视为equal除非它们是同一个对象(即它是“对象标识”,即x == y).
  • 默认实现equals() and hashCode()for 记录将考虑所有组件(或字段)并比较它们是否相等(或考虑它们的哈希码)。如果它们都匹配那么.equals()将返回true and hashCode将返回相同的值。

记录的详细信息java.lang.Object.hashCode() https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#hashCode() are:

就合理实用而言,Object 类定义的 hashCode 方法为不同的对象返回不同的整数。

实际上,这意味着任何不覆盖的对象hashCode其类型层次结构中的任何位置都将返回所谓的“身份哈希代码”,它实际上是一个任意但恒定的数字。

As for java.lang.Record.hashCode() https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Record.html#hashCode(), 它说:

隐式提供的实现返回通过组合来自每个组件的适当散列而派生的散列码值。隐式提供的实现中使用的精确算法未指定,并且可能会在上述限制内发生变化。即使组件值的散列以这种方式保持一致,从应用程序的一次执行到同一应用程序的另一次执行,所得到的整数不需要保持一致。此外,原始类型的组件可以将其位贡献给散列码,其方式不同于其原始包装类的散列码。

And for equals()方法;

java.lang.Object.equals(Object obj) https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#equals(java.lang.Object) :

Object 类的 equals 方法实现了对象上最具辨别力的可能等价关系;也就是说,对于任何非空参考值 x 和 y,当且仅当 x 和 y 引用同一个对象时此方法返回 true(x == y 的值为 true)。换句话说,在引用相等等价关系下,每个等价类只有一个元素。

java.lang.Record.equals(Object obj) https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Record.html#equals(java.lang.Object) :

当且仅当参数是与此记录相同的记录类的实例,并且此记录的每个组件等于参数的相应组件时,隐式提供的实现才返回 true;否则,返回 false。分量 c 的相等性确定如下: 如果组件是引用类型,当且仅当 Objects.equals(this.c, r.c 返回 true 时,组件才被视为相等。 如果组件是原始类型,使用相应的原始包装类 PW(int 的相应包装类是 java.lang.Integer 等),当且仅当 PW.compare(this. c, r.c) 将返回 0。 除了上述语义之外,隐式提供的实现中使用的精确算法未指定,并且可能会发生变化。该实现可能会也可能不会使用对列出的特定方法的调用,并且可能会也可能不会按照组件声明的顺序执行比较。

更多讨论请参见JEP 395:记录 https://openjdk.java.net/jeps/395.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 中记录与类的 hashCode() 和 equals() 的默认实现 的相关文章

随机推荐

  • 数据库结果的数组结构

    这可能是一个非常微不足道的问题 但是以下哪种方法是构造返回数据库结果的数组的最佳实践 比如说博客文章列表 对文章进行排序和分组 或者对元素进行排序和分组 Array title gt Array 0 gt Untitled 1 gt Unt
  • current_prolog_flag double_quotes DCG(代码或字符)?

    在使用 SWI Prolog DCG 时 我注意到有些人注意到 set prolog flag double quotes codes Jan http www swi prolog org pldoc man section string
  • 为什么正则表达式 ((x,y)|(x,z)) 是不确定的?

    为什么正则表达式 x y x z 像 Core Java 一书中所说的那样是不确定的 作者给出了他的观点 当解析器看到 x 时 它不知道采取两个替代方案中的哪一个 这个表达式可以以确定性形式重写为 x y z 谁能给我一个解释吗 为了具有确
  • Android 活动上下文为空

    所以我这里有这些代码 它运行时不会崩溃 但是 当我将 this 传递到网格适配器时 mContext 为空 我尝试传递 getApplicationContext 但仍然无法使 getImage 方法正常运行 因为 getResources
  • 我将如何获得 WPF Windows 应用程序的许可[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我开发了一个小型应用程序 我想尝试并销售它 但我不熟悉如何最好地做到这一点 我将如何锁定该程序以供试用1 我将如何处理接受付款 考虑到
  • SASS 或 LESS 关键帧百分比循环

    我正在测试一些特殊的东西 我正在尝试在关键帧内循环以动态地将百分比写入其中 我已经用 SASS 测试过类似的东西 但它不起作用 keyframes test for i from 0 through 100 i do special stu
  • Mercurial:保持两个分支同步但存在某些持久差异?

    我是一名使用 django 自己工作的 Web 开发人员 我正在尝试了解如何最好地使用 Mercurial 部署网站 我想要的是能够保留一个可用于生产和开发工作的存储库 生产 开发之间总会存在一些差异 例如 它们可能使用不同的数据库 开发总
  • docker 容器中的 Rails 应用程序在开发中不会重新加载

    我跟着这个docker compose 教程 https docs docker com compose rails 关于如何启动 Rails 应用程序 它运行完美 但当我更改控制器时 应用程序不会重新加载 还可以缺少什么吗 我也遇到了这个
  • 在 R6 类上定义括号 (`[`) 运算符

    这是不起作用的 library R6 Foo R6 R6Class Foo public list X NULL metadata NULL initialize function X metadata self X X self meta
  • DropDownListFor, selected = true 不起作用

    Select 对于 DropDownListFor 不起作用 谁能帮我 我有音乐类别和属于某一音乐类别的艺术家 在我的页面上 我想显示艺术家详细信息 并且我希望下拉列表加载所有音乐类别 并选择指定的艺术家音乐类别 但我无法在下拉列表中选择一
  • 找不到 boost_process cmake find_package

    我正在尝试将 boost 库导入到我的 C 项目中 由于某种原因 它找不到 Boost Process 尽管它找到了其他库 我的 CMakeLists txt 文件 cmake minimum required VERSION 3 9 FA
  • Python从某个元素开始重新排列列表

    我有一个 python 列表和一个项目的索引 我想在列表上从索引后面的元素开始循环 例如我有 original list 1 2 3 4 5 my index 2 new list 4 5 1 2 3 我正在努力实现新的清单 只需使用列表s
  • 在 R 中正确使用“ClusterEval”?

    我正在使用 R 编程语言 我有这个数据集 记录一组学生在不同时间的考试结果 1 通过 0 失败 library data table library doParallel Generate some sample data id sampl
  • 我可以将reveal.js 幻灯片对齐到页面顶部吗?

    我正在使用reveal js 并试图弄清楚如何强制我的幻灯片到页面的最左上角 这看起来应该很简单 但是当我使用元素检查器时 它从根本上改变了页面 以至于我什至无法开始将幻灯片移至顶部的归零 将其添加到我的主题中 reveal slides
  • 查看x86架构中的cpu缓存内容

    如何查看或转储基于 x86 的架构的 cpu 缓存内容 每次进行缓存刷新时 我如何才能看到刷新了什么 在哪里 你不能 真的 CPU 缓存被设计为对于 CPU 上运行的代码是透明的 它具有加快代码执行速度的效果 但 CPU 管理有关缓存的所有
  • 你能在 Clojure 中将插入排序表示为幺半群吗?

    这是 Clojure 中插入排序的代码 defn in sort data letfn insert raw x insert raw x sorted y raw x if nil y conj sorted x if lt x y co
  • Angular-i18n 代码翻译的解决方法?

    我们必须等到 Angular 6 的 Angular i18n 才能支持错误消息等代码的翻译 对于那些使用 angular i18n 例如 而不是 ngx translate 的人来说 您同时在做什么来处理代码中的翻译 我突然想到 如果字符
  • 选择选择框时,从表单(视图)中的文本框检索值到 codeigniter php 中的控制器

    查看页面代码 td align left valign middle class rows td
  • strings.xml:错误:多次找到项目字符串/按钮

    strings xml Error Found item String button more than one time 如何摆脱这个问题 帮助 在您的情况下 您不能有多个具有相同名称 按钮 的字符串 为每个人指定唯一的名称 如下所示
  • Java 中记录与类的 hashCode() 和 equals() 的默认实现

    尝试使用示例代码来检查默认行为equals and hashCode for record vs class 但它的行为似乎有所不同record相比于class 这是代码示例record and class public class Equ