正确的实施方式等于合同 [英] Right way to implement equals contract

查看:102
本文介绍了正确的实施方式等于合同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为用户的域对象。用户的属性包括ssoId,name,email,createdBy,createdDate和userRole。其中, ssoId必须是唯一的,因为没有两个用户可以拥有相同的sso id。所以我的equals方法检查sso id并返回true或false。

I have a domain object called User. Properties of user include ssoId, name, email, createdBy, createdDate and userRole. Of these, ssoId must be unique in the sense no two users can have the same sso id. So my equals method checks for the sso id and returns either true or false.

@Override public boolean equals(Object o) {
    if (!(o instanceof User))
      return false;
    return user.getSsoId().equals((User)o.getSsoId());
}

我觉得这是一个不正确的实现,尽管它是正确的就业务规则而言。对于具有相同sso id但具有不同的名称或电子邮件或两者的值的两个对象,上述实现将返回true。我应该更改我的等于合同以检查所有字段的相等性吗?你的建议是什么?

What I feel is that this is an incorrect implementation, though it is correct as far as the business rules are concerned. The above implementation will return true for two objects with same sso id but with different values for say name or email or both. Should I change my equals contract to check the equality of all fields? What is your suggestion?

推荐答案

这对于技术平等来说(几乎)是正确的,但不是自然平等。要实现最高技术平等,您还应该测试反身 o == this 。可能会发生该对象尚未持久保存在DB中,因此尚未拥有技术ID。例如,

This is (almost) correct for "technical equality", but not for "natural equality". To achieve top technical equality, you should also test the reflexive o == this. It may happen that the object isn't persisted in DB yet and thus doesn't have a technical ID yet. E.g.

public class User {

    private Long id;

    @Override
    public boolean equals(Object object) {
        return (object instanceof User) && (id != null) 
             ? id.equals(((User) object).id) 
             : (object == this);
    }

    @Override
    public int hashCode() {
        return (id != null)
             ? (User.class.hashCode() + id.hashCode())
             : super.hashCode();
    }

}

对于自然平等,你应该而是比较所有非技术属性。对于真实世界实体而言,这比技术上的平等更加强大(但也更昂贵)。

For "natural equality" you should rather compare all non-technical properties. For "real world entities" this is after all more robust (but also more expensive) than technical equality.

public class User {

    private String name;
    private Date birth;
    private int housenumber;
    private long phonenumber;

    @Override
    public boolean equals(Object object) {
        // Basic checks.
        if (object == this) return true;
        if (!(object instanceof User)) return false;

        // Property checks.
        User other = (User) object;
        return Objects.equals(name, other.name)
            && Objects.equals(birth, other.birth)
            && (housenumber == other.housenumber)
            && (phonenumber == other.phonenumber);
    }

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

}

是的,那是很多代码有很多属性。有点像IDE(Eclipse,Netbeans等)可以自动生成 equals() hashCode()(还有 toString(),getters和setter)。利用它。在Eclipse中,右键单击代码并查看 Source (Alt + Shift + S)菜单选项。

True, that's lot of code when there are a lot of properties. A bit decent IDE (Eclipse, Netbeans, etc) can just autogenerate equals(), hashCode() (and also toString(), getters and setters) for you. Take benefit of it. In Eclipse, rightclick code and peek the Source (Alt+Shift+S) menu option.

  • JBoss: Equals and HashCode (in view of persistence)
  • Hibernate: Persistent Classes - implementing equals() and hashCode()
  • Related SO question: Overriding equals and hashCode in Java

这篇关于正确的实施方式等于合同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆