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

示例代码会尝试检查的默认行为的equals()()哈希码进行记录VS,但似乎表现不同的记录比较

这是记录类的代码示例

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 和 hashcode 实现发生变化。那么请帮助我了解该更改的确切目的以及在哪些情况下使用它会更有帮助。

约阿希姆·绍尔

简而言之,区别很简单:

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

详细记录的详细信息java.lang.Object是:

尽可能实用,类 Object 定义的 hashCode 方法确实为不同的对象返回不同的整数。(在某个时间点,hashCode 可能会也可能不会被实现为对象内存地址的某个函数。)

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

而对于java.lang.Record它说

当且仅当参数是与此记录相同的记录类的实例,并且此记录的每个组件都等于参数的相应组件时,隐式提供的实现才返回 true;否则,返回 false。分量 c 的相等性确定如下:

  • 如果组件是引用类型,则当且仅当 Objects.equals(this.c, rc 将返回 true。
  • 如果组件是原始类型,使用对应的原始包装类 PW(int 对应的包装类是 java.lang.Integer,依此类推),当且仅当 PW.compare(this. c, rc) 将返回 0。

除了上述语义之外,隐式提供的实现中使用的精确算法是未指定的,并且可能会发生变化。实现可能会或可能不会使用对列出的特定方法的调用,并且可能会或可能不会按照组件声明的顺序执行比较。

(那些是针对各自的hashCode方法,equals方法有相似的语言)。

有关更多讨论,请参阅JEP 395:记录

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

hashCode和equals在int [] Java中的实现

在Java中为我的对象实现Equals和hashCode

实现hashCode和equals方法,但类是最终的

Java中==,equals和hashcode的示例

Java中的equals()和hashCode()协定

Java中的哪些类正在重写equals()和hashCode()方法?

Java:自动equals()和hashCode()

Java equals()和hashCode()的更改

在Java中为具有循环引用的对象实现equals和hashCode

Nashorn,Java集合,如何在纯JavaScript中实现equals和hashCode

如果我的类在Java中实现了可比性,是否需要一个equals和Hashcode方法?

如何在JPA的BaseEntity中实现equals()和hashcode()方法?

为什么要在Java中同时覆盖equals()和hashCode()?

Java中的hashCode和equals方法之间的关系

为什么需要覆盖Java中的equals和hashCode方法?

如何实现hashCode和equals方法

equals和hashCode的可重用实现

我应该在域类中实现equals和hashCode吗?

是否有可能在Java中制作类似于Comparator的内容,但用于实现自定义的equals()和hashCode()

SonarLint警报为Java:S1206的问题,但的hashCode和equals实现

在Eclipse中调试equals()和hashCode()

即使我实现了所有的hashCode(),equals()和toString(),也应该使用数据类吗?

Java对象的默认hashCode()实现

hashcode()和equals()方法

hashCode和equals方法中的异常在Java中是否被允许和接受?

在继承层次结构中实现健壮的equals()和hashCode()方法的正确方法是什么?

如何实现hashCode和equals方法以从ArrayList中删除重复项

使用Mojo Jaxb2 Maven插件创建Java类时生成hashCode()和equals()

哪个内置的Java类不会覆盖equals和hashcode方法?为什么?