简体   繁体   中英

Overriding equals and hashCode on a POJO with a List object

I have a 2 POJOs that look like this

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

}

And I need to verify if two Container objects are the same. I looked a bit and I found that apache commons has HashCodeBuilder and EqualsBuilder that help overriding those methods. The idea is that those builder methods use all the elements in an Object in order to determine the HashCode and the equality of two objects. The problem is that, if you see the example code, it looks like this:

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();
  }

How can I append the List<Element> elements ? Do I need to create another method just to parse the whole List into a String for this to work? Thanks!

Short version:

Yes, you can use the append method of EqualsBuilder and HashCodeBuilder .

Long version:

The List.equals(Object) method compares all the elements on the list. See the javadoc

Compares the specified object with this list for equality. Returns true if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal. (Two elements e1 and e2 are equal if (e1==null ? e2==null : e1.equals(e2)).) In other words, two lists are defined to be equal if they contain the same elements in the same order. This definition ensures that the equals method works properly across different implementations of the List interface.

So you could use append(elements, rhs.elements) to compare the lists.

The List.hashCode() also use the hashCode of the elements, so also can use the append method of HashCodeBuilder . The javadoc says:

Returns the hash code value for this list. The hash code of a list is defined to be the result of the following calculation:

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

I believe both Apache Commons and auto-generated code by IDEs are based on guidelines by Joshua Block in his book Effective Java .

In case you use an IDE such as Eclipse you can generate equals() and hashCode() automatically by choosing which fields you would like to include in the computation. Eclipse even let's you use your own custom equals() and hashCode() builders , or Apache Commons' for that matter.

I also have the same problem with you.I tried to generate equals(), hashCode() and toString() methods and the code work well. Here is my code:

public class EmployeeIncomeTaxRespiteDto extends 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 + "]";
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM