Reputation: 97
I have a class with some String parameters. I made a list of instances from this object. Then I made a comparator sort function to sort the list by different topics. For example by StartTime or EndTime. The time is defined in String format. Here is the compare function for sort:
if (sortType == Sort.STARTTIME){
Collections.sort(routeList, new Comparator<Route>() {
@Override
public int compare(Route o1, Route o2) {
if (Double.parseDouble(o1.getTimeS()) >= (Double.parseDouble(o2.getTimeS())))
return 1;
else
return -1;
}
});
}
It works but when I change the comparator with > or < or <= sign it will not work! or when I compare them with endTime , then only works with <= and I cannot sort it in an increasing order!!!! Even I cannot change the place ot 1 and -1.
if (sortType == Sort.ENDTIME){
Collections.sort(routeList, new Comparator<Route>() {
@Override
public int compare(Route o1, Route o2) {
if ((Double.parseDouble(o1.getTimeE()) <= Double.parseDouble(o2.getTimeE()))))
return 1;
else
return -1;
}
});
}
I really don't know what is the matter with it!!!!!!!
public class Route extends Arc {
private String type;
private int secId;
private String tId;
private int event;
private String name;
private String nameS;
}
private String nameE;
private String timeS;
private String timeE;
.....
}
And here are some lines of data
57779.999999999985 57779.999999999956 57778.999999999985 57778.99999999994 57778.99999999993 57778.99999999988 57777.0 57777.0 57750.0 57749.99999999994 57734.99999999994 57734.99999999988 57719.999999999985 57719.999999999985
Upvotes: 2
Views: 73
Reputation: 7371
When use a comparator you implement the logic of comparison.
Then in the following code:
public int compare(Route o1, Route o2) {
if (Double.parseDouble(o1.getTimeS()) >= (Double.parseDouble(o2.getTimeS())))
return 1;
else
return -1;
}
You are basically comparing doubles "Double.parseDouble". If you want compare strings you can use compareTo method as follows:
public int compare(Route o1, Route o2) {
return o1.type1.compareTo(o2.type1);
}
Assuming that type1 attributes for o1 and o2 will never be null else you need to improve the code.
The point is: Inside compare method you must need provide the logic for compare two objects. Imagine that you have a class Student:
public class Student {
public int id;
public String name;
public double score;
public Student (int id, String name, double score) {
this.id = id;
this.name = name;
this.score = score;
}
}
And two instances:
Student foo = new Student(100,"Foo", 10.5);
Student bar = new Student(50,"Bar", 90.5);
For sorting purposes which of following is true?:
foo > bar
bar > foo
foo == bar
Java doesn't know you must provide the logic:
if you wat to order by id:
public int compare(Student s1, Student s2) {
return s1.id - s2.id;
}
if you wat to order by name:
public int compare(Student s1, Student s2) {
return s1.name.compareTo(s2.name);
}
if you wat to order by score in descendent way:
public int compare(Student s1, Student s2) {
return (s2.score - s1.score) * 100;
}
Upvotes: 0
Reputation: 140447
Your understanding of comparators is wrong.
They ought to return -1, 1, and 0 when things are equal. Thus you current comparison using <= and returning either -1 or 1 is incorrect.
Instead, you have to implement such logic that:
Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
In other words: your first implementation probably worked for that data you tested with; but it is incorrect; and reversing the logic doesn't fix that problem.
Finally: the easy answer here; simply use Double.compare() within your comparator. As comparing floating point numbers is actually a tricky business.
Upvotes: 6
Reputation: 97
The right answer
public int compare(Route o1, Route o2) {
if (Double.parseDouble(o1.getTimeS()) < (Double.parseDouble(o2.getTimeS())))
return -1;
else if (Double.parseDouble(o1.getTimeS()) == (Double.parseDouble(o2.getTimeS())))
return 0;
else
return +1;
}
});
Upvotes: 0