java - Unable to replicate : "Comparison method violates its general contract!" -


i receive following error: "comparison method violates general contract!" when using following comparator, unable replicate exception using junit. i'd know caused issue , how replicate it. there examples of others having same problem not how replicate it.

public class dtocomparator implements comparator<dto> {      @override     public int compare(dto r1, dto r2) {          int value = 0;          value = r1.getorder() - r2.getorder();          if (value == 0 && !isvaluenull(r1.getdate(), r2.getdate()))             value = r1.getdate().compareto(r2.getdate());          return value;     }      private boolean isvaluenull(date date, date date2) {         return date == null || date2 == null;     } } 

the code called using:

collections.sort(dtos, new dtocomparator()); 

thanks help.

extra info: error seemed occur in timsort class inside java utils , within method called mergelo. link: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/timsort.java#timsort.mergelo%28int%2cint%2cint%2cint%29

from documentation of compare.

the implementor must ensure sgn(x.compareto(y)) == -sgn(y.compareto(x)) x , y

subtraction-based comparators not meet condition. because subtraction can overflow. example

integer.min_value - 0 0 - integer.min_value  

are both negative.

there problem way have dealt dates. documentation of compare:

finally, implementor must ensure x.compareto(y)==0 implies sgn(x.compareto(z)) == sgn(y.compareto(z)), z.

your compare method breaks this. example, if x null, y january 1st 1970 , z january 2nd 1970, then

compare(x, y) == 0  // x == null compare(x, z) == 0  // x == null compare(y, z) == -1 // january 1st before january 2nd. 

i write method follows:

@override public int compare(dto r1, dto r2) {      int value = integer.compare(r1.getorder(), r2.getorder());     if (value != 0)         return value;     date date1 = r1.getdate();     date date2 = r2.getdate();     if (date1 == null && date2 == null)         return 0;     if (date1 == null)         return -1;     if (date2 == null)         return 1;     return date1.compareto(date2); }  

i have managed reproduce problem, lists of length @ least 32. see link explanation of why list of size @ least 32 required. why program using collections.sort fail lists of size 32 or more?

public class main {      private static final class numanddate {         private final int num;         private final date date;          numanddate(int num, date date) {             this.num = num;             this.date = date;         }     }      public static final class numanddatecomparator implements comparator<numanddate> {          @override         public int compare(numanddate r1, numanddate r2) {              int value = 0;              value = r1.num - r2.num;              if (value == 0 && !isvaluenull(r1.date, r2.date))                 value = r1.date.compareto(r2.date);              return value;         }          private boolean isvaluenull(date date, date date2) {             return date == null || date2 == null;         }     }      public static void main(string[] args) {         numanddate[] array = {                 new numanddate(0, new date(0)),                 new numanddate(0, new date(1)),                  new numanddate(0, null)         };         random random = new random();         (int = 0; < 100; i++) {             (int j = 0; j < 10000; j++) {                 list<numanddate> list = new arraylist<>();                 int[] arr = new int[i];                 (int k = 0; k < i; k++) {                     int rand = random.nextint(3);                     arr[k] = rand;                     list.add(array[rand]);                 }                 try {                     collections.sort(list, new numanddatecomparator());                 } catch (exception e) {                     system.out.println(arr.length + " " + arrays.tostring(arr));                     return;                 }             }         }     } } 

Comments

Popular posts from this blog

jquery - How do you format the date used in the popover widget title of FullCalendar? -

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -