2

Comparison method violates its general contract

I am sorting by rating which is a double. Can anyone see why i am getting this error?

Collections.sort(productsMasterList, new Comparator<Product>() {
    @Override
    public int compare(Product o1, Product o2) {
        final double rating1 = o1.getRating();
        final double rating2 = o2.getRating();
        boolean realisticRating1 = rating1 < 4.8;
        boolean realisticRating2 = rating2 < 4.8;
        return rating1 > rating2 && realisticRating1 ? -1 : rating2 > rating1 && realisticRating2 ? 1 : 0;
    }
});

edit: This is not a duplicate because it is very specific to me. i have seen other answers but i still can't figure out why i am getting this error, my code seems like it should work fine

124697
  • 22,097
  • 68
  • 188
  • 315
  • @YoungHobbit not a duplicate. please see the edit: – 124697 Dec 15 '15 at 18:14
  • 1
    These are known as canonical posts. _very specific to me_ is only useful to you, not to the community. That's why we try to have posts that apply to all (or at least most) cases. That post applies to your case. – Sotirios Delimanolis Dec 15 '15 at 18:17
  • 1
    This is a non-transitive sort function. Imagine values {3, 4, 5}. Your sort algorithm would say 3 = 5, 4 = 5, but 3 != 4. – Flying_Banana Dec 15 '15 at 18:19
  • 1
    @SotiriosDelimanolis: The proposed duplicate is very specific to that other OP's code. If you want to create a canonical post, that would be great -- I'd upvote you -- but that post is not it. – ruakh Dec 15 '15 at 18:19
  • 1
    This proposed duplicate is less than stellar, in that the accepted answer incorrectly claims that the comparator violates transitivity (cf. the [heavily upvoted comment about that](http://stackoverflow.com/questions/11441666/java-error-comparison-method-violates-its-general-contract#comment-38775853)), while it actually violates anti-symmetry, while the comparator in the present question actually violates transitivity. – meriton Dec 15 '15 at 18:43

1 Answers1

8

Consider these three ratings:

1
3
5    // unrealistic

According to your comparator, unrealistic ratings compare equal to all other ratings; so even though 1 and 3 are not equivalent to each other, they are both equivalent to 5. So your comparator doesn't implement a transitive relation, so the client of your comparator can't get consistent results; everything comes out wonky.

ruakh
  • 175,680
  • 26
  • 273
  • 307