简体   繁体   English

equals合同的重要字段是什么(有效的java项目8)

[英]What is a significant field for the equals contract (effective java item 8)

In Effective Java in Item 8 the recommendation is that 在第8项的Effective Java中,建议是这样的

For each significant field in the class to check the corresponding field of the this object. 对于类中的每个重要字段,检查对象的相应字段。

I understand that we can have secondary fields that are calculated by primary fields but what exactly is the meaning of "for each significant field"? 我知道我们可以有主要字段计算的辅助字段,但“每个重要字段”的含义究竟是什么? Is the equals contract implemented properly only when all fields of an object is compared? 仅当比较对象的所有字段时,是否正确实现了equals合约?

If I have eg a class Employee which has a multitude of fields like id, first and last name, dob, position, location etc all these seem significant but to me it seems that just using the id would suffice for a proper and performant equals implementation. 如果我有一个类Employee ,它有很多字段,如id,名字和名字,dob,位置,位置等所有这些看起来很重要,但对我来说,似乎只需使用id满足正确和equals实现。

Am I wrong on this? 我错了吗? Or the id I mention is exactly what Bloch means by "significant" fields? 或者我提到的id正是Bloch在“重要”字段中的含义?

class Employee {

    private UUID id;
    private String firstName;
    private String lastName;

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!(obj instanceof Employee))
            return false;
        return id.equals(((Employee)obj).id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

In case of Employee is stored into DB, ie has unique id , then no need to check other fields like firstName and lastName in equals ; 如果Employee存储到DB中,即具有unique id ,则不需要检查equals firstNamelastName等其他字段; according to data object comparison, only id filed is significant . 根据数据对象的比较,只有id字段很重要

A significant field is merely one that, if omitted, would result in an incorrect implementation of equals (according to the notion of equality you have defined for instances of your class). 一个重要的字段只是一个,如果省略,将导致equals的错误实现(根据您为类的实例定义的相等概念)。

I appreciate that is a bit of a self-referential definition, but that's what it means. 我很欣赏这是一个自我指涉的定义,但这就是它的含义。

The canonical example of a non-significant field is String.hashCode : as you observe, this is calculated from other fields (and lazily), so it would not be appropriate to include in the equality because there is no guarantee that it has been calculated for either of the strings being compared; 非重要字段的规范示例是String.hashCode :正如您所观察到的,这是从其他字段(和懒惰)计算的,因此不适合包含在相等中,因为不能保证它已被计算对于任何一个被比较的字符串; and, if it has been calculated for both, it tells you nothing more than you already know. 并且,如果已经计算了两者,它只会告诉你比你已经知道的更多。

In your case, yes, it sounds like comparing instances using only the id would suffice: this is a significant field, the name (etc) is not significant: there should only be one person (little p, as in an actual real human) with a particular id. 在你的情况下,是的,这听起来像仅仅使用id比较实例就足够了:这是一个重要的字段,名称(等)并不重要:应该只有一个人(小p,如在真正的真实人类中)有一个特定的身份证。

It does raise a question of how you would deal with "same id, different name" instances, but this is getting into the realm of Falsehoods Programmers Believe About Names : 它确实提出了一个问题,即如何处理“相同的id,不同名称”实例,但这进入了Falsehoods程序员相信名称的领域

  1. People have exactly one canonical full name. 人们只有一个规范的全名。
  2. People have exactly one full name which they go by. 人们只有一个完整的名字。
  3. People have, at this point in time, exactly one canonical full name. 在这个时间点,人们只有一个规范的全名。
  4. People have, at this point in time, one full name which they go by. 在这个时间点,人们有一个他们经过的全名。
  5. People have exactly N names, for any value of N. 对于任何N值,人们都有N个名字。
  6. (People's names fit within a certain defined amount of space.) (人们的名字在一定的空间内。)
  7. People's names do not change. 人们的名字不会改变。
  8. ... ...

Taking these into consideration, if you want to say "this Person is the same as that Person" (and you want to do that using equals ), id seems like the only reasonable thing to use. 考虑到这些,如果你想说“这个人和那个人一样”(并且你想用equals做),id似乎是唯一合理的用法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM