Comparison method violates its general contract Exception
Asked Answered
A

2

3

Below is a block of code that results in exception as indicated,

Code :

Collections.sort( arrayList, 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;
    }
} );

Exception :

java.lang.IllegalArgumentException: Comparison method violates its general contract!
                at java.util.TimSort.mergeLo(TimSort.java:747)
                at java.util.TimSort.mergeAt(TimSort.java:483)
                at java.util.TimSort.mergeForceCollapse(TimSort.java:426)
                at java.util.TimSort.sort(TimSort.java:223)
                at java.util.TimSort.sort(TimSort.java:173)
                at java.util.Arrays.sort(Arrays.java:659)
                at java.util.Collections.sort(Collections.java:217)

When I run the same code as a standalone program, the issue never occurs. What is the issue with the comparator here? Is there a way to reproduce the issue in a standalone code?

This issue occurs only on Java 1.7 as there has been change in the implementation on Arrays.sort & Collections.sort. How to change the above code to avoid the issue?. Also, how to reproduce this issue in a standalone code?

Arrangement answered 18/4, 2013 at 8:58 Comment(4)
if order is of type Integer you could return tas1.order.compareTo(tas2.order)Analyzer
what do you mean by 'standalone program'? Or rather, what other option of running the code you are referring to?Wb
possible duplicate of "Comparison method violates its general contract!"Interfile
You already asked this question: compare method violates its general contract exception java 7Benjie
D
3

You need to return 0 on equal objects.

        if ( tas1.order < tas2.order ){
            return -1;
        } else if ( tas1.order == tas2.order ){
            return 0;
        } else {
            return 1;
        }

You can read here more

Deluxe answered 18/4, 2013 at 8:59 Comment(3)
But, why is the issue not reproduced when run as a standalone program where the value of intance variable order is maintained the same?Arrangement
compare must be transitive. Your code isn't. So instead of working incorrectly, it states to you that your code is buggy. I think it is a very good behavior.Deluxe
@baraky You might expect to write tas1.order == tas2.order, you surely missed the double "=" instead of ... assignment ;)Palinode
P
-1

In your comparator, for A == B, compare(A,B) returns 1 (A>B), but compare(B,A) still returns 1 (meaning B>A). If the sorting algorithm detects this contradiction, it throws an exception instead of maybe endlessly looping or recursing.

Photoreconnaissance answered 5/4 at 14:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.