From the JavaDoc of TreeMap :
Note that the ordering maintained by a sorted map (whether or not an explicit comparator is provided) must be consiste
Say we have this simple Student
class implementing Comparable
but not overriding equals()
/hashCode()
. Of course equals()
is not consistent with compareTo()
- two different students with the same age
aren't equal:
class Student implements Comparable {
private final int age;
Student(int age) {
this.age = age;
}
@Override
public int compareTo(Student o) {
return this.age - o.age;
}
@Override
public String toString() {
return "Student(" + age + ")";
}
}
We can safely use it in TreeMap
:
Map students = new TreeMap();
students.put(new Student(25), "twenty five");
students.put(new Student(22), "twenty two");
students.put(new Student(26), "twenty six");
for (Map.Entry entry : students.entrySet()) {
System.out.println(entry);
}
System.out.println(students.get(new Student(22)));
The results are easy to predict: students are nicely sorted according to their age (despite being inserted in different order) and fetching student using new Student(22)
key works as well and returns "twenty two"
. This means we can safely use Student
class in TreeMap
.
However change students
to HashMap
and things go bad:
Map students = new HashMap();
Obviously the enumeration of items returns "random" order due to hashing - that's fine, it doesn't violate any Map
contract. But the last statement is completely broken. Because HashMap
uses equals()
/hashCode()
to compare instances, fetching value by new Student(22)
key fails and returns null
!
This is what the JavaDoc tries to explain: such classes will work with TreeMap
but might fail to work with other Map
implementations. Note that Map
operations are documented and defined in terms of equals()
/hashCode()
, e.g. containsKey():
[...] returns true if and only if this map contains a mapping for a key k such that
(key==null ? k==null : key.equals(k))
Thus I don't believe there are any standard JDK classes that implemente Comparable
but fail to implement equals()
/hashCode()
pair.