Just to elaborate more on this why compareTo() and equals() need to be consistent. The Sorted Set depends on the Object's compareTo() method to know whether a particular element can be added or not in the set and to avoid duplicate elements from being added into the set. So if this is the case , then it leads to ambiguity(copied from the specs):-
For example, if one adds two keys a and b such that (!a.equals(b) && a.compareTo(b) == 0) to a sorted set that does not use an explicit
comparator, the second add operation returns false (and the size of
the sorted set does not increase) because a and b are equivalent from
the sorted set's perspective.
To elaborate more, sorted set used compareTo() to check if the two elements a & b are equal or not and if the Class for a & b only overrides compareTo() method and not equals() method , then we could have a scenario where compareTo() method returns 0, but equals() method return false, which is quite weird and inconsistent. Let's say I have a Name class as shown below:-
public class Name implements Comparable<Name> {
private final String firstName, lastName;
public Name(String firstName, String lastName) {
if (firstName == null || lastName == null)
throw new NullPointerException();
this.firstName = firstName;
this.lastName = lastName;
}
public String firstName() {
return firstName;
}
public String lastName() {
return lastName;
}
/*public boolean equals(Object o) {
if (!(o instanceof Name))
return false;
Name n = (Name) o;
return n.firstName.equals(firstName) && n.lastName.equals(lastName);
}
public int hashCode() {
return 31 * firstName.hashCode() + lastName.hashCode();
}*/
public String toString() {
return firstName + " " + lastName;
}
public int compareTo(Name n) {
int lastCmp = n.lastName.compareTo(lastName);
return (lastCmp != 0 ? lastCmp : n.firstName.compareTo(firstName));
}
}
// Tester class main method has the below code
Name n1 = new Name("John", "Smith");
Name n2 = new Name("John", "Smith");
SortedSet<Name> mySet = new TreeSet<>();
System.out.println(mySet.add(n1));
System.out.println(n1.equals(n2));
System.out.println(n1.compareTo(n2));
System.out.println(mySet.add(n2));
The output is as shown below:-
true
false
0
false
Now this shows the ambiguity since we haven't overridden the equals() which in this case is returning false, but compareTo() is returning 0 and hence SortedSet considers the two objects n1 and n2 equal and hence adding n2 into the Set return false as shown in the sysout but they are not equal!!!
For more please refer to the stackoverflow link:-Comparator and equals()