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)
2
  • sort can't cause elements to get merged. Though if you were to use a Set, it would be a different story. Commented Jul 31, 2013 at 8:14
  • can you provide code of PositionComperator Commented Jul 31, 2013 at 8:30

3 Answers 3

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?

Sign up to request clarification or add additional context in comments.

1 Comment

@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.
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;
}

2 Comments

what does "return 0" will cause?
This means that they are equal and they will not be sorted. Have a look at the java doc for the compare method.
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;
            }
        }

2 Comments

why to use tree sort on list?
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. stackoverflow.com/questions/1463284/hashset-vs-treeset

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.