Comparison Method violates its general contract in Java 7
I am getting a "Comparison Method violates its general contract" after compiling some Java code in Java 7, and then running it.
I have read Comparison method violates its general contract! Java 7 only and realize that there is something wrong with my code that was ignored in previous versions of Java. However I cannot work out what is wrong with my code. The Collections.sort() generates the error.
My code is:
public Comparator sortBySmoothDays() {
Comparator c = new Comparator() {
public int compare(Object arg0, Object arg1) {
Date date0 = ((PosObject)arg0).getDate();
Date date1 = ((PosObject)arg1).getDate();
double d1 = MyUtils.calcSmoothDays(date0, new Date());
double d2 = MyUtils.calcSmoothDays(date1, new Date());
if (d1 >= d2) {
return 1;
}
else {
return -1;
}
}
};
return c;
}
Comparator c = ComparatorUtils.getInstance().sortBySmoothDays();
Collections.sort(posList, c);
Can anyone help? Thank you!
A comparator must return 0 if the values are equal. In your current implementation, you return 1 if they are equal. The easiest way to compare your double
values correctly is to call Double.compare
:
double d1 = MyUtils.calcSmoothDays(date0, new Date());
double d2 = MyUtils.calcSmoothDays(date1, new Date());
return Double.compare(d1, d2);
With your comparator, every object compares greater than itself: compare(x,x)
always returns one.
This violates the following requirement:
The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y.
The above requirement implies that compare(x,x)
must return zero.
I would recommend reading the contract and making sure your implementation fulfils it.
In particular, if date0.equals(date1)
, the comparator probably ought to return zero right away, without doing any floating-point conversions and comparisons.
Isnt the issue that if two objects compare equal i.e. calcSmoothDays returns the same value, then you could have a situation where compare(object1,object2) == 1, and compare (object2,object1) == 1 also?
So it implies that object1 > object 2 and object2 > object 1...