equals合同的一个重要字段是什么(有效java项目8)
在第8项中,建议如下: 为类中的每个重要字段检查此对象的对应字段 我知道我们可以用主字段计算辅助字段,但“每个重要字段”的确切含义是什么?只有在比较对象的所有字段时,equals合同的一个重要字段是什么(有效java项目8),java,class,oop,equals,hashcode,Java,Class,Oop,Equals,Hashcode,在第8项中,建议如下: 为类中的每个重要字段检查此对象的对应字段 我知道我们可以用主字段计算辅助字段,但“每个重要字段”的确切含义是什么?只有在比较对象的所有字段时,equals契约才能正确执行吗 例如,如果我有一个类Employee,它有许多字段,如id、名字和姓氏、dob、职位、位置等,所有这些似乎都很重要,但对我来说,仅仅使用id就足以实现适当且性能良好的equals实现 我错了吗?或者我提到的id正是布洛赫所说的“重要”字段的意思 如果员工存储在数据库中,即具有唯一id,则无需检查中的名
equals
契约才能正确执行吗
例如,如果我有一个类Employee
,它有许多字段,如id、名字和姓氏、dob、职位、位置等,所有这些似乎都很重要,但对我来说,仅仅使用id
就足以实现适当且性能良好的equals
实现
我错了吗?或者我提到的id
正是布洛赫所说的“重要”字段的意思
如果
员工
存储在数据库中,即具有唯一id
,则无需检查中的名字
和姓氏
等其他字段;根据数据对象比较,只有id
字段是有效的有效字段只是一个,如果省略,将导致不正确的相等实现(根据您为类实例定义的相等概念)
我理解这是一个自我参照的定义,但这就是它的意思
非重要字段的典型示例是String.hashCode
:正如您所观察到的,这是从其他字段计算出来的(并且是惰性的),因此不适合包含在等式中,因为无法保证它是为被比较的任何字符串计算出来的;而且,如果两者都计算过,它告诉你的只是你已经知道的
在您的情况下,是的,听起来只使用id
比较实例就足够了:这是一个重要字段,名称(etc)不重要:应该只有一个人(小p,就像真实的人类一样)具有特定的id
它确实提出了一个问题,即您将如何处理“相同id,不同名称”的实例,但这正进入以下领域:
人们只有一个规范的全名
人们只有一个全名
此时此刻,人们只有一个规范的全名
此时此刻,人们只有一个全名
人们有N个名字,N的任何值
(人名在一定的限定空间内。)
人们的名字不会改变
考虑到这些因素,如果你想说“这个人和那个人是一样的”(你想用等于),id似乎是唯一合理的用法。既然你写了这个类,你可以而且必须决定什么是“重要的”。可以比较对象的所有字段以验证euqality。请记住,在hashCode()
-实现中也要包含所有重要字段。@Turing85:我试图理解这本书是否暗示除其他人计算的字段之外的所有字段都是要使用的。是的,这是第9项。如果次要属性的计算是确定性的,并且只依赖于主要字段,我更愿意只使用主要字段。这样,就不必计算次要字段。根据id的定义,你不能有两个id相同但名称不同的实例(我没有否决投票,也不知道为什么会这样)@Jim在这种情况下,你仍然没有问题,只是根据id进行比较。我指的是你的句子,它确实提出了一个你将如何处理的问题“同一个id,不同的名字”的例子,
我无法理解,因为id
根据定义应该表示一些独特的东西,对吗?@Jim我的意思是,比如说,你的政府标识符(国家保险号、社会保险号等)已修复,但您可以更改名称。您可以在更改名称之前创建Person
的实例,也可以在更改名称之后创建实例。
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);
}
}