【问题标题】:Overriding equals and hashCode on a POJO with a List object使用 List 对象覆盖 POJO 上的 equals 和 hashCode
【发布时间】:2015-07-08 23:59:02
【问题描述】:

我有 2 个类似这样的 POJO

public class Element{
   private String name;
   private int number;
   //GETTERS AND SETTERS
}

public class Container{
    private String subject;
    private String email; 
    private List<Element> elements;
    //GETTERS AND SETTERS

}

我需要验证两个 Container 对象是否相同。我看了看,发现 apache commons 有 HashCodeBuilderEqualsBuilder 帮助覆盖这些方法。这个想法是那些构建器方法使用对象中的所有元素来确定 HashCode 和两个对象的相等性。问题是,如果你看到示例代码,它看起来像这样:

public boolean equals(Object obj) {
   if (obj == null) { return false; }
   if (obj == this) { return true; }
   if (obj.getClass() != getClass()) {
     return false;
   }
   MyClass rhs = (MyClass) obj;
   return new EqualsBuilder()
                 .appendSuper(super.equals(obj))
                 .append(field1, rhs.field1)
                 .append(field2, rhs.field2)
                 .append(field3, rhs.field3)
                 .isEquals();
  }

如何附加List&lt;Element&gt; elements?我是否需要创建另一种方法来将整个 List 解析为 String 才能正常工作?谢谢!

【问题讨论】:

  • 如果你可以依赖“List”的“equals”和“hashCode”实现,那么根据这个,(commons.apache.org/proper/commons-lang/apidocs/org/apache/…)我假设你可以将它添加到构建器中。列表的顺序必须相同才能相等,每个元素和存储在列表中的类型也应该有相等和哈希码。
  • 有趣...我想,为了让两个具有相同元素但顺序不同的列表被视为相等,我可以对它们进行排序。我会尝试一下,看看它是如何工作的。
  • 或者根本不使用List,如果顺序不重要,使用Set
  • 小心这个。如果您要处理 大量 量的数据,重复调用 toString()(在示例的 log.info() 中),那么您可能会通过如此深入的检查来创建性能瓶颈。

标签: java apache equals hashcode


【解决方案1】:

我相信 Apache Commons 和 IDE 自动生成的代码都基于 Joshua Block 在他的书 Effective Java 中的指导方针。

如果您使用诸如 Eclipse 之类的 IDE,您可以通过选择您希望在计算中包含哪些字段来自动生成 equals() 和 hashCode()。 Eclipse 甚至可以让你use your own custom equals() and hashCode() builders,或者 Apache Commons'。

【讨论】:

    【解决方案2】:

    我也有同样的问题。我尝试生成 equals()、hashCode() 和 toString() 方法并且代码运行良好。 这是我的代码:

    公共类 EmployeeIncomeTaxRespiteDto 扩展 AbstractDto {

    private static final long serialVersionUID = 2305082424321176578L;
    
    private Integer employeeId;
    
    private String employeeName;
    
    private List<IncomeTaxRespiteSelectDto> incomeTaxRespiteList;
    
    @Override
    public boolean equals(Object object) {
        return EqualsBuilder.reflectionEquals(this, object);
    }
    
    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }
    
    @Override
    public String toString() {
        return "EmployeeIncomeTaxRespiteDto [employeeId=" + employeeId + ", employeeName=" + employeeName + ", incomeTaxRespiteList=" + incomeTaxRespiteList + "]";
    }
    

    }

    【讨论】:

      【解决方案3】:

      短版:

      是的,你可以使用EqualsBuilderHashCodeBuilderappend方法。

      长版:

      List.equals(Object) 方法比较列表中的所有元素。见javadoc

      比较指定对象与此列表是否相等。当且仅当指定的对象也是一个列表时返回 true,两个列表具有相同的大小,并且两个列表中所有对应的元素对都相等。 (如果 (e1==null ? e2==null : e1.equals(e2)) 两个元素 e1 和 e2 相等。)换句话说,如果两个列表以相同的顺序包含相同的元素,则它们被定义为相等.此定义可确保 equals 方法在 List 接口的不同实现中正常工作。

      因此您可以使用append(elements, rhs.elements) 来比较列表。

      List.hashCode()也使用元素的hashCode,所以也可以使用HashCodeBuilderappend方法。 javadoc 说:

      返回此列表的哈希码值。列表的哈希码定义为以下计算的结果:

      int hashCode = 1;
      for (E e : list)
          hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-04
        • 1970-01-01
        • 2020-06-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多