0

I am trying to reproduce this exception (java.lang.IllegalArgumentException: Comparison method violates its general contract!) as I need to debug a piece of code, but the code below never throws it,

try {
  ArrayList al = new ArrayList();
  for (int i = 1; i <= 36; i++) {
    TypeAdapterSort t = new TypeAdapterSort();
    t.order = i;
    al.add(t);
  }
  System.out.println(al.size());
  Collections.sort(al, new Comparator() {
    public int compare(Object o1, Object o2) {
      TypeAdapterSort tas1 = (TypeAdapterSort) o1;
      TypeAdapterSort tas2 = (TypeAdapterSort) o2;
      if (tas1.order < tas2.order)
        return -1;
      else
        return 1;
    }
  });

} catch (Exception e) {
  System.out.println(e);
}

Also, when I checked the JDK code it seems that this exception is thrown by Collections.sort method only when the size of the collection to be sorted is greater than 32?. What change should be made in the code block so that Collections.sort throws this exception.

Mohan
  • 155
  • 1
  • 4
  • 10
  • Yes, this piece of code throwed the exception on dataset which I do not know. As I know only the exception, i want it to reproduced so that I can determine what type of data causes it to occur. – Mohan Apr 19 '13 at 07:46
  • @MarcoForberg By my count it's [the seventh](http://stackoverflow.com/users/901975/mohan?tab=questions&sort=newest). – Duncan Jones Apr 19 '13 at 07:48
  • yes. the three times i mentioned were the ones i saw with my own eyes ;) – Marco Forberg Apr 19 '13 at 07:50
  • @Marco : I never got any solution for reproducing this exception, any piece of code that does this will be of great help!! – Mohan Apr 19 '13 at 07:54

2 Answers2

6

This is probably your problem

if (tas1.order < tas2.order)
    return -1;
else
    return 1;

If the order is equal you'll get a different result depending which on goes into the Comparator first, which is not right.

The contract is something like if A < B and B < C then A < C, but in your case this can be broken depending which order the arguments get passed.

try something like

return tas1.order -tas2.order;

This also explains why you can't reproduce it as your test data never has duplicates. try adding some dupes in your test data and see if you can reproduce (before applying the fix obviously...)

John3136
  • 28,809
  • 4
  • 51
  • 69
  • Thanks for the reply. My question is on reproducing the error. Why is the above code not throwing the exception?. – Mohan Apr 19 '13 at 07:44
  • @Mohan edited my answer to describe reproducing it about 2 secs before I saw your comment ;-) – John3136 Apr 19 '13 at 07:44
  • Thanks John. But, I have tried duplicates in the data and the exception never came up. Any piece of code that throws this exception will be of great help!!. Thanks – Mohan Apr 19 '13 at 07:51
  • Try adding your items in a different order – John3136 Apr 19 '13 at 07:55
2

If objects are equal you never return 0. The library is smart enough to detect this

Eugene
  • 117,005
  • 15
  • 201
  • 306