什么是用于覆盖 hashcode() 和 equals() 方法的 HashCodeBuilder 和 EqualsBuilder?

What is HashCodeBuilder and EqualsBuilder which is used in overriding the hashcode() and equals() method?

我必须覆盖实体 class 的 equals() 方法和 hascode() 方法。 但我的问题是为什么要使用 HashcodeBuilder 和 EqualsBuilder 来实现它。

这两个哪个更好,为什么?

  @Override
public int hashCode()
{
    return HashCodeBuilder.reflectionHashCode(this, false);
}

@Override
public boolean equals(Object obj)
{
    return EqualsBuilder.reflectionEquals(this, obj);
}

@Override
public int hashCode()
{
    final int prime = 31;
    int result = 1;
    result = prime * result + ((userKey == null) ? 0 : userKey.hashCode());
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    result = prime * result + ((userEntity == null) ? 0 : userEntity.hashCode());
    return result;
}

@Override
public boolean equals(Object obj)
{
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    UserKeyEntity other = (UserKeyEntity) obj;
    if (UserKey == null)
    {
        if (other.userKey != null)
            return false;
    }
    else if (!userKey.equals(other.userKey))
        return false;
    if (id == null)
    {
        if (other.id != null)
            return false;
    }
    else if (!id.equals(other.id))
        return false;
    if (userEntity == null)
    {
        if (other.userEntity != null)
            return false;
    }
    else if (!userEntity.equals(other.userEntity))
        return false;
    return true;
}

为什么?

第二个默认由 STS IDE 创建。 请告诉我第一个选项到底是什么以及为什么要选择?

HashcodeBuilder和EqualsBuilder会影响性能,因为它使用了反射,比第二个慢。

您可以使用 IDE 生成的 HashcodeBuilder 和 EqualsBuilder。

HashcodeBuilder 和 EqualsBuilder 将易于阅读、理解及其动态。

就我个人而言,我不会使用反射来计算 equals 和 hashcode。

如文档所述(对于 EqualsBuilder.reflectionEquals):

It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will throw a security exception if run under a security manager, if the permissions are not set up correctly. It is also not as efficient as testing explicitly. Non-primitive fields are compared using equals().

所以

  • 你在做危险的操作(你甚至不确定你不会得到 SecurityException
  • 它不太有效,因为您使用反射来计算这些值

作为个人观点,我真的觉得使用反射来计算您的 class 中的 equals 和 hashcode 是胡说八道。就像用错了工具。

由于您已经在使用第三方库,我会像这样使用 HashCodeBuilder :

@Override
public int hashCode() {
    return new HashCodeBuilder().append(userKey)
                                .append(id)
                                .append(userEntity)
                                .toHashCode();
}

等同:

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    UserKeyEntity other = (UserKeyEntity) obj;
    return new EqualsBuilder().append(userKey, other.userKey)
                              .append(id, other.id)
                              .append(userEntity, other.userEntity)
                              .isEquals();
}

比Eclipse生成的可读性好一点,而且不使用反射。