124697
124697

Reputation: 21893

Sorting throws java.lang.IllegalArgumentException: Comparison method violates its general contract

I have this method that contains two comparators for sorting items by price.

This works fine 90% of the time but sometimes it throws the exception in the title. Anyone know why

void sort(
    Collections.sort(masterList, new Comparator<Item>() {
    @Override
    public int compare(Item o1, Item o2) {
        try {
            if (o1.getPriceLevel() == 999 && o1.getPriceLevel() < o2.getPriceLevel()) {
                return 1;
            }
            if (o2.getPriceLevel() == 999) {
                return -1;
            }
            return Double.compare(o1.getPriceLevel(), o2.getPriceLevel());
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }

    }
    });
//Null pointer happens on the line below
    Collections.sort(masterList, Collections.reverseOrder(new Comparator<Item>() {
    @Override
    public int compare(Item o1, Item o2) {
        try {
            if (o1.getPriceLevel() == 999 || o2.getPriceLevel() == 999) {
                return 1;
            }
            return Double.compare(o1.getPriceLevel(), o2.getPriceLevel());

        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    }));
}

edit: stacktrace

java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(TimSort.java:743)
at java.util.TimSort.mergeAt(TimSort.java:479)
at java.util.TimSort.mergeCollapse(TimSort.java:406)
at java.util.TimSort.sort(TimSort.java:210)
at java.util.TimSort.sort(TimSort.java:169)
at java.util.Arrays.sort(Arrays.java:2038)
at java.util.Collections.sort(Collections.java:1891)

Upvotes: 2

Views: 6922

Answers (1)

light_303
light_303

Reputation: 2111

This is a check in the TimSort algorithm used by Java7 - which validates that your comparator method is valid ( e.g. symetric- a == b && b == a )

your equals case is invalid (returning 0) - it depends on the order the arguments are given if one element is null. Try to handle null values explicitly before doing anything else e.g.:

if(o1 == null || o2 == null)
{
    return 0;
} 

Upvotes: 5

Related Questions