Reputation: 395
The error that i was facing in this Question has been solved and is written below in answer section.
The problem was that the below definition of TreeMap is throwing a compiler error and I wanted to know the reason.
Comparator<Student> comparator=new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// TODO Auto-generated method stub
if(o1.roll<=o2.roll)
return -1;
else return 1;
}
};
TreeMap<Integer, Student> map=new TreeMap<>(comparator);
I dont understand the reason this implementation of Treemap is wrong. Can anyone please explain me about what is going on in here?
Upvotes: 1
Views: 2996
Reputation: 86232
TL;DR: A comparator for a TreeMap<Integer, Student>
needs to compare Integer
s, not Student
s.
A TreeMap<Integer, Student>
maps from integers (“the keys”) to student objects (“the values”) and keeps the mappings sorted by the integers. Therefore the constructor does not accept a Comparator<Student>
as argument.
According to the documentation of TreeMap<K,V>
, the constructor taking a comparator as argument is declared as
TreeMap(Comparator<? super K> comparator)
This means that the comparator must work on type K
, the type of the keys, or some supertype of K
. In your case, K
is Integer
.
Since the Integer
class already defines an ordering, the so-called natural ordering, I suggest you don’t need a comparator at all:
TreeMap<Integer, Student> map = new TreeMap<>();
If you wanted to store the students by their roll
number, just insert them like this:
Student me = new Student();
map.put(me.roll, me);
The side effect will be that the map is sorted by roll
.
PS The information in the answer by John Kugelman is correct too, a comparator needs to handle three cases. And Comparator.comparingInt(s -> s.roll)
or Comparator.comparingInt(Student::getRoll)
(if the class has such a getter) is recommended, not only for the terseness, even more because it’s less error-prone.
Upvotes: 2
Reputation: 361585
compare()
needs to handle three cases: less than, greater than, and equal. You need to return 0
when they're equal.
if (o1.roll == o2.roll) {
return 0;
}
else if (o1.roll < o2.roll) {
return -1;
}
else {
return 1;
}
Integer.compare(int x, int y)
can do all of this for you:
public int compare(Student o1, Student o2) {
return Integer.compare(o1.roll, o2.roll);
}
In Java 8 you can create the entire comparator in a single line:
Map<Integer, Student> map = new TreeMap<>(Comparator.comparingInt(s -> s.roll));
Upvotes: 6