I am looking at some legacy code and I found a section that is causing me to get a “Comparison method violates its general contract!” error. I understand that this error is the result of the code not being transitive, but I don't fully understand how to fix it correctly.
Here is the code responsible for the error.
private void sortHistories(List<History> histories) {
Collections.sort(histories, new Comparator<History>() {
@Override
public int compare(History o1, History o2) {
return o1 == o2 ? 0
: o1 == null ? -1
: o2 == null ? 1
: o1.getFamilyMembers().equals(o2.getFamilyMembers()) ? 0 //getFamilyMembers() returns a string
: o1.getFamilyMembers() == null ? -1
: o2.getFamilyMembers() == null ? 1
: o2.getFamilyMembers().compareTo(o2.getFamilyMembers()) != 0 ?
o2.getFamilyMembers().compareTo(o2.getFamilyMembers())
: o1.getDisease().equals(o2.getDisease()) ? 0 //getDisease() also returns a string
: o1.getDisease() == null ? -1
: o2.getDisease() == null ? 1
: o1.getDisease().compareTo(o2.getDisease());
}
});
}
Originally, the code was using ==
rather than equals()
when comparing the strings getDisease()
and getFamilyMembers()
. I thought making the change from ==
to equals()
would fix the problem, but that is not the case.
The solution, thanks to HaifengZhang and YoungHobbit, is: