实现等于()方法设计模式



是否有任何设计模式(或习惯用法)可以帮助在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)。


我真的不喜欢看到truefalse的显式使用,尤其是当它们直接脱离评估逻辑时。

因此,当在类中重写和实现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));
}

每行执行细节:

  1. (this == o)-检查完全相同的实例
  2. (o instanceof EqualsExampleClass that)-检查以确保o不是nullo是此类的实例(或子类),如果是,则将o分配给缩小类型变量that
  3. (this.getClass() == that.getClass())-要求与完全相同的类(而不是子类)进行比较
  4. Objects.equals(this.stringy, that.stringy)-在引用(而不是基元)上使用Objects.equals(),以确保如果任何一方返回null,则在不抛出NullPointerException的情况下进行比较

我发现这种代码实现模式在重构过程中更容易进行功能流读取、分析、推理和调试

不确定您的期望值。equals()用于定义比较类中两个不同对象以获得相等性的标准。

通常,您可以逐个比较每个属性,但只使用较少的选定属性进行比较是非常可能的,也是非常受支持的。

最新更新