Julian Os
Julian Os

Reputation: 281

Java: Comparison method violates its general contract

I got the exception from above which I know was discussed often here on SO. Anyways, the others don't tell me what's wrong with my code. These StyleAlbum are just Music albums. getAdded() returns the time when their last song was added to Android's MediaStore in milliseconds as int. This happens only on some devices!

Code:

public static List<StyleAlbum> sortAdded() {
    List<StyleAlbum> mAlbums = new ArrayList<>();
    mAlbums.addAll(Library.getAlbums());
    Collections.sort(mAlbums, new Comparator<StyleAlbum>() {
        @Override
        public int compare(StyleAlbum lhs, StyleAlbum rhs) {
            if (lhs.getAdded() > rhs.getAdded()) {
                return -1;
            } else return 1;
        }
    });
    return mAlbums;
}

Upvotes: 0

Views: 54

Answers (2)

Raffaele
Raffaele

Reputation: 20885

Your comparator does not account for two items being equal, ie it never returns zero. You should use something like

return Integer.compare(lhs.getAdded(), rhs.getAdded());

otherwise the result is at least inconsistent, and depending on the algorithm it may even be completely wrong. In this case, Tim sort (the algorithm used in the JDK) is smarter enough to tell you that there's an error.

Note: I compared integers with Integer.compare instead of a subtraction (thanks Louis Wasserman) to avoid overflow errors

Upvotes: 1

J Fabian Meier
J Fabian Meier

Reputation: 35843

You should return 0 in the compare method if both values are the same. Especially, a comparison from an object to itself should give 0.

Upvotes: 0

Related Questions