Mihawk
Mihawk

Reputation: 835

Java Collections.Sort Comparison method violates its general contract

I'm getting an error in my code since yesterday and I'm not sure why! I googled a lot and found this Stack-Post.

I use this funtion to sort users by name and create date. This function has worked since 2 years and now I'm getting an error for one user and I don't know what has changed. I tried to check my data if there is anything corrupt but couldn't find anything wrong.

After reading zhe Stack-Post I still didn't understand fully what's the problem or what has changed in my project.

public void sortUsers(List<Users> sortList) {
    Collections.sort(sortList, new Comparator<Users>() {
        public int compare(Users user1, Users user2) {
            Integer comp = 0;
            comp = user1.getUsername().compareTo(user2.getUsername());
            if (comp == 0) {
                comp = user1.getCreateDate().before(user2.getCreateDate()) ? -1 : 1;
            }

            return comp;
        }
    });
}

Upvotes: 0

Views: 111

Answers (1)

Andy Turner
Andy Turner

Reputation: 140484

comp = user1.getCreateDate().before(user2.getCreateDate()) ? -1 : 1;

This line can never return zero, in the case that the dates are equal. This means that it's not anti-symmetric (i.e. sgn(a.compareTo(b)) = -sgn(b.compareTo(a))).

The exact fix depends on what class getCreateDate() returns, but it could be something like:

comp = user1.getCreateDate().compareTo(user2.getCreateDate());

However, an easier way to do construct a compliant comparator would be:

Comparator.comparing(Users::getUsername).thenComparing(Users::getCreateDate)

or similar.

Upvotes: 8

Related Questions