Patan
Patan

Reputation: 17893

equals(Object obj)" should be overridden along with the "compareTo(T obj)" method

I am writing a comparable class. I have overridden compareTo method to sort my objects based on date in descending order.

public class Employee implements Comparable<Employee>
{
    
    private Timestamp joinDate;
   
    public Timestamp getJoinDate()
    {
        return joinDate;
    }

    public void setJoinDate(Timestamp joinDate)
    {
        this.joinDate = joinDate;
    }

    @Override
    public int compareTo(Employee a)
    {
        //sort employess based on join date desc
        return a.getJoinDate().compareTo(this.getJoinDate());
    }
   
}

My Sonar is complaing to override equals method.

How do I override equals method here.

Upvotes: 0

Views: 6466

Answers (3)

Alexey Malev
Alexey Malev

Reputation: 6533

There is a difference between what what is indicated by .equals() == true and .compareTo(...) == 0. equals() method is intended to check whether two objects are equal, while compareTo is intended to set a relation order between elements, whether one is greater then the other, other is greater then the first one, or none of this is applicable which is typically means that objects are equal.

Unless you have a very good reason, you should override both equals and compareTo. An example of very good reason is BigDecimal class where equals compares both value of the object and its scale, while compareTo compares only values.

For your case, I'd override equals() like this:

@Override 
public int hashCode() {
    return this.getJoinDate().hashCode();
}

@Override
public boolean equals(Object obj) {
    //correct argument check
    if (!(obj instanceof Employee)) {
         return false;
    }

    //check nulls
    if (obj == null) {
        return false;
    }
    Employee other = (Employee) obj;
    if (this.getJoinDate() == null) {
        return other.getJoinDate() == null;
    }
    return this.getJoinDate().equals(other.getJoinDate());
}

Upvotes: 1

Andres
Andres

Reputation: 10725

Include this on your class (when you override equals, you have to also override hashCode):

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((joinDate == null) ? 0 : joinDate.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;
    Snippet other = (Snippet) obj;
    if (joinDate == null) {
        if (other.joinDate != null)
            return false;
    } else if (!joinDate.equals(other.joinDate))
        return false;
    return true;
}

Upvotes: 2

Christian Tapia
Christian Tapia

Reputation: 34166

If you want to override the method compareTo, you have to use the same signature. The actual signature uses an Object parameter:

@Override
public int compareTo(Object o)
{
    return ((Employee) o).getJoinDate().compareTo(joinDate);
}

Note that you have to explicitly cast the object obj to Employee, otherwise you won't be able to call its method getJoinDate().

Edit: If you want to override the equals() method you can return the result of comparing the attributes joinDate:

@Override
public boolean equals(Object obj)
{
    return joinDate.equals(((Employee) obj).getJoinDate());
}

Note: It's not necessary to call getJoinDate() inside the Employee class, so you can just do:

return ((Employee) o).joinDate.compareTo(joinDate);

or

return joinDate.equals(((Employee) obj).joinDate);

Upvotes: 2

Related Questions