Java - Comparable interface with very small number

Viewed 55

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

1 Answers

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.)

Related