Reputation: 10412
In an android application, I have a list of locations. I need to sort them based on their distance with the user location. for that I implemented a custom comparator:
Collections.sort(houseList, new Comparator<HouseEntity>()
{
@Override
public int compare(HouseEntity house1, HouseEntity house2)
{
if(userLocation == null) return 0;
return (int) (userLocation.distanceTo(house1.location) - userLocation.distanceTo(house2.location));
}
});
It is working well on all the testings I made. However some users had a crash with the following error:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
After reading all the other same issues on SO I concluded that this error appears when there might be an error in the logic (for example we might get a>b and b>a in the same time). But I couldn't find any scenario to replicate that logic error.
What scenario could be causing this error? And how can I solve it?
Thanks a lot for any help
Upvotes: 1
Views: 144
Reputation: 30874
As Peter Lawrey said, you should use Double.compare(x, y)
or Float.compare(x, y)
instead of casting to int. Here the explanation:
Comparator MUST be transitive, i.e. whenever A == B and B == C, then also A == C. Lets imagine we have three points A
, B
and C
with the distances to the user location 0.2, 0.4 and 1.3.
A == B
B == C
A < C
As you can see the comparator is not transitive.
Upvotes: 1
Reputation: 1001
If userLocation == null
then house1.equals(house2)
should give true.
Upvotes: 0