2

I have this class that stores the latitude and the longitude of a coordinate and it distances from the center. At some point in my algorithm I have a list of these Coordinate and I want to sort them by their distance from the center. Thus, I implemented the Comparable interface and it compareTo method.

public class Coordinate implements Comparable<Coordinate> {
    
    private Double lat;
    private Double lon;
    private Double distanceCenter;
    
    protected Coordinate(Double lon, Double lat, Double distanceFromCenter) {
        this.lat=lat;
        this.lon=lon;
        this.distanceCenter=distanceFromCenter;
    }
    
    public Double getDistanceFromCenter() {
        return distanceFromCenter;
    }
    
    @Override
    public int compareTo(Coordinate compared) {
        return (int) ((this.distanceCenter) - (compared.getDistanceCenter()));
    }
}

The problem is that sometimes the difference between the two points is too small (almost zero) and java throws a

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

I solved the problem just multiplying each distance for a really high number so to avoid any "loss of significance" effect

@Override
public int compareTo(Eq compared) {
    return (int) ((this.distanceCenter*1000000000000000.0) (compared.getDistanceCenter()*1000000000000000.0));
}

I would like to know if there is a more elegant way to solve this type of problem or if I'm doing something wrong

Dan
  • 3,647
  • 5
  • 20
  • 26
ale666
  • 41
  • 4

1 Answers1

7

The appropriate solution is just to use

return Double.compare(distanceCenter, compared.getDistanceCenter);

...and, in fact, it's very rare that you should use subtraction in a compareTo method at all. Instead, you should use the appropriate compare method. (Even for ints, using subtraction for compareTo implementations can be quite broken.)

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413