java - Android - Comparison method violates its general contract -


i've seen other questions exception compare method simple i'm unable figure out what's wrong , can't reproduce of android devices own.

i'm getting exception users of android app, of seem on new devices gs3 or gs4, i'm guessing run java 7 variant of merge sort.

here's compare method:

            collections.sort(collectionofthings, new comparator<thing>()             {                 public int compare(thing lhs, thing rhs)                  {                     //getdist() returns double capital d...perhaps has it?                     if(lhs.getdist() < rhs.getdist())                     {                         return -1;                     }                     if(lhs.getdist() == rhs.getdist())                     {                         return 0;                     }                      return 1;                 };             }); 

here's exception:

caused by: java.lang.illegalargumentexception: comparison method violates general contract!     @ java.util.timsort.mergelo(timsort.java:743)     @ java.util.timsort.mergeat(timsort.java:479)     @ java.util.timsort.mergecollapse(timsort.java:404)     @ java.util.timsort.sort(timsort.java:210)     @ java.util.timsort.sort(timsort.java:169)     @ java.util.arrays.sort(arrays.java:2038)     @ java.util.collections.sort(collections.java:1891) 

seems limited android 4.0+. appreciated.

no use in re inventing wheel. believe should return lhs.getdist().compareto(rhs.getdist()); , let provided implementation compareto job .

compares 2 double objects numerically.

there 2 ways in comparisons performed method differ performed java language numerical comparison operators (<, <=, ==, >=, >) when applied primitive double values:

  1. double.nan considered method equal , greater other double values (including double.positive_infinity).

  2. 0.0d considered method greater -0.0d.

this ensures natural ordering of double objects imposed method consistent equals.

i believe exception because present implementation may not apt deal double.nan , positive/negative zero values , and yet honor general contract. @ openjdk double#compare(double,double) source code :

public static int more ...compare(double d1, double d2) {    if (d1 < d2)         return -1;           // neither val nan, thisval smaller     if (d1 > d2)         return 1;            // neither val nan, thisval larger      long thisbits = double.doubletolongbits(d1);     long anotherbits = double.doubletolongbits(d2);      return (thisbits == anotherbits ?  0 : // values equal             (thisbits < anotherbits ? -1 : // (-0.0, 0.0) or (!nan, nan)              1));                          // (0.0, -0.0) or (nan, !nan) } 

also go through documentation of double#equals()

note in cases, 2 instances of class double, d1 , d2, value of d1.equals(d2) true if , if d1.doublevalue() == d2.doublevalue()

also has value true. however, there 2 exceptions:

if d1 , d2 both represent double.nan, equals method returns true, though double.nan==double.nan has value false. if d1 represents +0.0 while d2 represents -0.0, or vice versa, equal test has value false, though +0.0==-0.0 has value true.


Comments