This site is currently read-only as we are migrating to Oracle Forums for an improved community experience. You will not be able to initiate activity until January 31st, when you will be able to use this site as normal.

    Forum Stats

  • 3,890,738 Users
  • 2,269,776 Discussions
  • 7,916,827 Comments

Discussions

java.lang.IllegalArgumentException: Comparison method violates general.....

1004808
1004808 Member Posts: 6
edited Apr 23, 2013 6:48PM in Java Programming
Below code throws java.lang.IllegalArgumentException: Comparison method violates its general contract!,

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;
}
} );

class TypeAdapterSort {
int order;
}

I am not sure with what data in arraylist the above code throws the exception, please me know the data that needs to be populated in arraylist so that the exception occurs.
Tagged:
«1

Answers

  • Kayaman
    Kayaman Member Posts: 3,844 Silver Trophy
    The method needs to return 0 for equal objects, or -1/1 for smaller/bigger. Your method doesn't return 0 in any case.
  • 1004808
    1004808 Member Posts: 6
    Even then, when i run the above code with a smaller dataset like an arraylist with values 1, 2, 3, 4, 5 it executes with no exceptions, it is only under certain conditions it throws exceptions.

    As I am not sure on the data that causes this issue, what elements should i populate in the arraylist above so that the exception is thrown?.
  • gimbal2
    gimbal2 Senior software engineer NetherlandsMember Posts: 11,949 Gold Trophy
    1001805 wrote:
    Even then, when i run the above code with a smaller dataset like an arraylist with values 1, 2, 3, 4, 5 it executes with no exceptions, it is only under certain conditions it throws exceptions.
    So apparently whatever logic is in there that checks it can only properly do so when the list has sufficient values in it
    As I am not sure on the data that causes this issue, what elements should i populate in the arraylist above so that the exception is thrown?.
    You'd have to check the source code. But the real fix is to just follow the contract as documented in the javadocs.
  • 1004808
    1004808 Member Posts: 6
    Yes, following the contract will avoid the exception. But is exception not thrown with a smaller dataset of arraylist with 1,2,3,4,5 as it's elemensts in the above code.

    Is there i specific limitation on the size of arraylist and the manner in which it needs to contain the elements for the exception to be thrown?
  • sabre150
    sabre150 Member Posts: 1,405
    edited Apr 23, 2013 5:48AM
    I don't see how that exception can be thrown since unless the comparator code is analysed at runtime nothing will know that zero is never returned.
  • 1004808
    1004808 Member Posts: 6
    Yes, very true. What pattern of data (equal elements, ascending, descending etc) can cause this comparator throw the exception java.lang.IllegalArgumentException while passing it as a parameter to Collections.sort?.

    I need this pattern of data or any sample data that fails this code. Any sample data with few elements that make the code fail will be of great help!!.

    Also, this exception can be thrown only if the size of the collection to be sorted is greater that 32 as per the JDK.

    JDK 1.7 uses binarysort to sort the elements if the collections size < 32 and does not throw the exception in this case.

    If the collection size is > 32 it uses Tim sort and also throws the exception if the comparison contract is violated.
  • sabre150
    sabre150 Member Posts: 1,405
    edited Apr 23, 2013 6:08AM
    1001805 wrote:
    Yes, very true. What pattern of data (equal elements, ascending, descending etc) can cause this comparator throw the exception java.lang.IllegalArgumentException while passing it as a parameter to Collections.sort?.
    The comparator can't throw that exception! The comparator does not analyse itself.

    >
    I need this pattern of data or any sample data that fails this code. Any sample data with few elements that make the code fail will be of great help!!.
    I really don't understand what you are asking here.

    >
    Also, this exception can be thrown only if the size of the collection to be sorted is greater that 32 as per the JDK.
    Sorry but nothing in the Javadoc I have says anything about the magic number 32 and it surely is irrelevant since I can't see that Collections.sort() method analysing the comparator code (but see my later comment about compare(a,a) ).

    >
    JDK 1.7 uses binarysort to sort the elements if the collections size < 32 and does not throw the exception in this case.
    Surely irrelevant!

    >
    If the collection size is > 32 it uses Tim sort and also throws the exception if the comparison contract is violated.
    All I can imagine is that somewhere in the Collections.sort() method a comparator.compare(a,a) is done and it detects that zero is not returned.

    Whatever the source of the problem the solution is to fix the comparator so that it does not violate the contract!

    P.S. Should you not be working with templates.
  • 1004808
    1004808 Member Posts: 6
    To clarify further, let us consider the below example where al is an arraylist of Integer objects,

    Collections.sort(al, new Comparator() {
    public int compare(Object o1, Object o2) {
    Integer tas1 = (Integer) o1;
    Integer tas2 = (Integer) o2;
    if (tas1.intValue < tas2.intValue)
    return -1;
    else
    return 1;
    }
    });

    What Integer objects should the arraylist contain so that the exception "java.lang.IllegalArgumentException: Comparison method violates general....." is thrown?.

    I can say that a random sample like Integer(1001), Integer(1000), Integer(1000), Integer(1004) does not throw the exception, even though it contains two equal integer objects.
  • Kayaman
    Kayaman Member Posts: 3,844 Silver Trophy
    1001805 wrote:
    What Integer objects should the arraylist contain so that the exception "java.lang.IllegalArgumentException: Comparison method violates general....." is thrown?.
    Why do you even care about that? You're breaking the contract and it's being noticed, which is somewhat exceptional since for example the equals() method won't tell you that if you implement it wrong.

    Why don't you write the compare method correctly?
  • jtahlborn
    jtahlborn Member Posts: 2,040
    1001805 wrote:
    What Integer objects should the arraylist contain so that the exception "java.lang.IllegalArgumentException: Comparison method violates general....." is thrown?.
    easy enough, just figure out what collection violates line 746 here:

    http://www.docjar.com/html/api/java/util/TimSort.java.html
This discussion has been closed.