Yet another programmers blog

The new experiences of a new programmer

Comparison method violates its general contract!

with 4 comments

java.lang.IllegalArgumentException: Comparison method violates its general contract!

Well, this is definitely the weirdest Java exception I’ve had so far. I got it on a Comparator I wrote, which returned either -1 or 1 (no == check was performed , and I never returned 0) .

This will happen to you usually when switching to Java 7 from older versions of Java. (Happened  to me when I switched from 6 to 7)

Long story short , the solution was to add the following line (Which is generally a good idea) to your Comparator :

if (o1 == o2) return 0;

Why does it happens ? Well, according to Java 7 change set, they replaced the merge sort implementation , and from now on

The new sort implementation may throw an IllegalArgumentException if it detects a Comparable that violates the Comparable contract.

 

Why is that important to them? I have no idea, but I’m guessing maybe the new merge sort works better when some elements are equal (i.e , the compartor returns 0), and having a “bad” comprator hinders performances. .

What I do fail to understand is why this contract validity test done on runtime and not on compilation time!

Written by yossale

December 8th, 2011 at 6:57 pm

Posted in Java,Programming

4 Responses to 'Comparison method violates its general contract!'

Subscribe to comments with RSS or TrackBack to 'Comparison method violates its general contract!'.

  1. Hi, thanks for your solution. I got exact the same Exception after I upgrade my JDK to 1.7

    But after I added if (o1 == o2) return 0; to my comparator. I am still getting the same Exception.

    Do you know any other way I need to do to fix this problem?

    Thanks!

    Thomas

    15 Feb 12 at 20:25

  2. Are you sure you’re covering all the scenarios? meaning , for each value (1,0,-1) there a scenario that returns it? (and there’s no other scenarios)

    yossale

    15 Feb 12 at 20:44

  3. Hi
    I had the same problem, but in my case it was because of comparing double values with and ==. After I used Double.compare method it worked :).

    Before:
    return (o1.getDouble() < o2.getDouble() ? -1 : (o1.getDouble() == o2.getDouble() ? 0 : 1));

    After:
    return Double.compare(o1.getDouble(), o2.getDouble());

    Maybe it will help someone in the future :)
    Bye and have a nice day.

    Bladito

    27 Mar 12 at 22:28

  4. Hi,
    I was facing the same issue after upgrading to jdk 1.7

    This solution works perfectly

    Thanks

    syaoran

    21 Aug 14 at 11:16

Leave a Reply