是否有任何设计模式(或习惯用法)可以帮助在Java中实现equals()
方法
这项任务并不难,但在大多数情况下都差不多。。。这就是为什么我想有一个模式,但我没有找到它。
UPDATE
我选择了方法:generate equals() method in Eclipse
但是。。。我(在AbstractList中)找到了一个让生成的代码变得更好的好方法:
if (!(attributes ==null ? other.attributes==null : attributes.equals(other.attributes)))
return false;
而不是生成:
if (attributes == null) {
if (other.attributes != null)
return false;
} else if (!attributes.equals(other.attributes))
return false;
通常要实现equals()方法,我所做的是:我从Eclipse中生成这些,因为Eclipse可以很好地生成hashCode、toString和equals(。
我总是使用以下代码:
if (null == obj) return false;
if (this == obj) return true;
if (!(object instanceof MyClass)) return false;
MyClass that = (MyClass) obj;
EqualsBuilder eb = new EqualsBuilder();
eb.append(this.businessKey, that.businessKey);
return eb.isEquals();
我从不使用序列或pk之类的技术密钥,总是使用业务字段。因此,我不认为这可以是通用的,但必须针对任何给定的类。
在某种意义上,两个对象何时"相同"在很大程度上取决于您自己。。。当它们包含相同的数据时(完全有效的用例),或者更严格地说,当它们是内存中的相同物理对象时(也是有效的),或者在集群环境中进行比较时,它们只是DB中的同一行时,它们应该相等吗?
只需记住也要覆盖.hashCode()
,否则你将陷入一个充满伤害的世界:-)
(还有来自@Andreas和@flash的好文章建议。)
干杯,
也许这有帮助:实现equals。特别要注意hashcode()和equals()之间的密切关系。除此之外,我想equals()的具体实现实际上取决于你的类设计,也就是说你什么时候平等对待两个对象。
看看Java语言规范是怎么说的。
equals
方法只是定义了对象相等的概念
除此之外,在设计此方法时没有涉及任何设计模式。事实上,equals
方法已经由Java语言设计人员设计,您只能使用该设计。如果你对如何编写自己的equals方法没有信心,可以考虑借助IDE,比如eclipse,它可以帮你完成任务。
此模式依赖于在Java 14(2020/Mar/17)中为预览发布的新instanceof
模式匹配功能,然后在Java 16中完全发布(2021/Mar/16)。
我真的不喜欢看到true
和false
的显式使用,尤其是当它们直接脱离评估逻辑时。
因此,当在类中重写和实现equals()
时,我一点也不喜欢IDE(IntelliJ)生成的默认代码模式。
它看起来像这样:
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
EqualsExampleClass that = (EqualsExampleClass) o;
return Objects.equals(stringy, that.stringy)
&& (inty == that.inty)
&& Objects.equals(bigIntegery, that.bigIntegery)
&& (booleany == that.booleany);
}
在OracleJEP394对instanceof
模式匹配的鼓励下,我重构了上面的代码,如下所示:
@Override
public boolean equals(Object o) {
return (this == o) ||
((o instanceof EqualsExampleClass that)
&& (this.getClass() == that.getClass())
&& Objects.equals(this.stringy, that.stringy)
&& (this.inty == that.inty)
&& Objects.equals(this.bigInt, that.bigInt)
&& (this.booleany == that.booleany));
}
每行执行细节:
(this == o)
-检查完全相同的实例(o instanceof EqualsExampleClass that)
-检查以确保o
不是null
,o
是此类的实例(或子类),如果是,则将o
分配给缩小类型变量that
(this.getClass() == that.getClass())
-要求与完全相同的类(而不是子类)进行比较Objects.equals(this.stringy, that.stringy)
-在引用(而不是基元)上使用Objects.equals()
,以确保如果任何一方返回null
,则在不抛出NullPointerException
的情况下进行比较
我发现这种代码实现模式在重构过程中更容易进行功能流读取、分析、推理和调试
equals()
用于定义比较类中两个不同对象以获得相等性的标准。
通常,您可以逐个比较每个属性,但只使用较少的选定属性进行比较是非常可能的,也是非常受支持的。