I Tried to do custom Ordering in my TreeMap based on length of string. Why am I getting only one Key if the length of the string is same despite being different strings.
How do I fix this and what are the implications for the equals meth0d, will it ever be used or will compareTo take its place.
The code:
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
public class Student implements Comparable {
int RollNo;
String Name;
public Student(int RollNo, String Name) {
this.RollNo = RollNo;
this.Name = Name;
}
public int compareTo(Object arg0) {
Student str = (Student) arg0;
return Integer.valueOf(str.Name.length()).compareTo(Integer.valueOf(this.Name.length()));
}
public static void main(String[] args) {
Map<Student, Integer> mp = new TreeMap<Student, Integer>();
mp.put(new Student(1, "Sameer"), 1);
mp.put(new Student(2, "Aameer"), 2);
for(Student st : mp.keySet()){
System.out.println((st.Name));
}
}
}
Your compareTo
method compares the lengths of the name String
s instead of their content, so Student
s having names with same length are considered identical by the TreeMap
.
In other words, the Comparable
or Comparator
used by the TreeMap
determines both ordering and uniqueness of the keys.
You can solve the issue by ordering the TreeMap
by both name length and name content (when the lengths are equal) :
public int compareTo(Object arg0) {
Student str = (Student) arg0;
int lengthComp = Integer.valueOf(str.Name.length()).compareTo(Integer.valueOf(this.Name.length()));
if (lengthComp == 0) {
// compare names if the lengths are equal
return str.Name.compareTo(this.Name);
} else {
return lengthComp;
}
}
Besides that, it's better for your class to implement Comparable<Student>
, which will allow your compareTo
method to accept a Student
argument.
How do I fix this and what are the implications for the equals meth0d, will it ever be used or will compareTo take its place.
equals
is not used by TreeMap
, and compareTo
indeed takes its place.