0

i use simple comperator and get exception and don't know what to do

this is how i call:

try {
   Collections.sort(this.closePositions, new PositionComperator());
}
catch(Exception e) {
   e.printStackTrace();
}

this is the comperator:

  public class PositionComperator implements Comparator<DataResponse> {

    @Override
    public int compare( DataResponse pos1, DataResponse pos2) {

        if (pos1.openTime >= pos2.openTime) {
            return 1;
        } 
        else {
            return -1;
        }// returning 0 would merge keys

    }

   }

this is the exception:

java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(Unknown Source)
at java.util.TimSort.mergeAt(Unknown Source)
at java.util.TimSort.mergeCollapse(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at GTTask.RefreshIdentityHistory.call(RefreshIdentityHistory.java:59)
at GTTask.RefreshIdentityHistory.call(RefreshIdentityHistory.java:1)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
swapy
  • 1,616
  • 1
  • 15
  • 31
user502967
  • 327
  • 1
  • 3
  • 13

3 Answers3

2

If two values x and y have the same openTime, then compare(x, y) and compare(y, x) will both return 1, which violates the contract of compare:

The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y.

You haven't ensured that.

You need to consider what you want to happen when the openTime values are the same - either return 0, or have some consistent notion of which value should come before the other. Do you have some secondary comparison you could perform, for example?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • @user502967: No, for exactly the reason I gave: if the two values are equal, you'll get 1 when comparing them both ways. Look at the contract for `compare`. – Jon Skeet Jul 31 '13 at 08:16
1

you can use treeSet. İt is sort it for you. And there is compare method. for example

TreeSet<Double> sortedSet = new TreeSet<Double>(); 

for example compare it

TreeSet<Double> set = new TreeSet<Rock>(new Comparator<Double>()
public int compare(Double a, Double b){
                return a.value - b.value;
            }
        }
user2583040
  • 83
  • 10
  • why to use tree sort on list? – user502967 Jul 31 '13 at 08:25
  • you can look this topic why you should use treeset. Treeset is directly sort and compare it you dont need another method and you can see more easy. http://stackoverflow.com/questions/1463284/hashset-vs-treeset – user2583040 Jul 31 '13 at 08:36
1

The reason you get this error is that when it sorted two items they changed order. You should also include the case where it is equal.

Preferably do:

return po1.openTime - pos2.opentime;

Or do

if (pos1.openTime > pos2.openTime) {
    return 1;
} 
else if (pos1.openTime < pos2.openTime) {
    return -1;
} else {
    return 0;
}
Knubo
  • 8,333
  • 4
  • 19
  • 25