在覆盖equalshashCode时必须考虑哪些问题/trap ?

推荐答案

该理论(适用于语言律师和有数学倾向的人):

equals()(javadoc)必须定义等价关系(必须是reflexivesymmetrictransitive).此外,它必须是consistent(如果对象没有修改,则它必须始终返回相同的值).此外,o.equals(null)必须始终返回false.

hashCode()(javadoc)也必须是consistent(如果对象没有按照equals()进行修改,它必须继续返回相同的值).

这两种方法之间的差异为:

Whenever 100, then 101 must be same as 102.

实际上:

如果覆盖一个,那么应该覆盖另一个.

使用与计算equals()hashCode()相同的字段集.

使用Apache Commons Lang库中的优秀助手类EqualsBuilderHashCodeBuilder.举个例子:

public class Person {
    private String name;
    private int age;
    // ...

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
            // if deriving: appendSuper(super.hashCode()).
            append(name).
            append(age).
            toHashCode();
    }

    @Override
    public boolean equals(Object obj) {
       if (!(obj instanceof Person))
            return false;
        if (obj == this)
            return true;

        Person rhs = (Person) obj;
        return new EqualsBuilder().
            // if deriving: appendSuper(super.equals(obj)).
            append(name, rhs.name).
            append(age, rhs.age).
            isEquals();
    }
}

还要记住:

当使用基于哈希的CollectionMap(例如HashSetLinkedHashSetHashMapHashtableWeakHashMap)时,请确保放入集合中的关键对象的hashCode()在对象位于集合中时不会更改.确保这一点的防弹方法是使你的 keys 不可变,which has also other benefits.

Java相关问答推荐

如何将一些命令写入Chrome控制台,然后使用Java将输出存储在selenium中

无法在Java中使用Curve secp 256 k1验证JWT

无法从Spring Boot应用程序连接到SQL Docker服务器

在Keycloak测试容器中的测试之间清理数据库

CSS应用于一个端点,但不应用于Thymeleaf中的另一个端点

';com.itextpdf.ext.html.WebColors已弃用

对于几乎不涉及逻辑的请求,您是否应该使用命令模式?

在bash中将数组作为Java程序的参数传递

从Spring5迁移到Spring6:无法在雅加达包中找到类

try 在Android Studio中的infoWindow中使用EditText(Java)

具有多个模式的DateTimeForMatter的LocalDate.parse失败

JavaFX标签中的奇怪字符

Oracle中从JSON中提取和插入数据

在Eclipse中可以使用外部字体吗?

如何对存储为字符串的大数字数组进行排序?

JPA无手术同品种器械可能吗?

在Java Spring JPA中插入包含对其他实体的引用的列

为什么没有加载java.se模块?

为什么使用lo索引来解决二进制搜索问题不同于使用hi索引?

为什么我得到默认方法的值而不是被覆盖的方法的值?