Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing a comparable for an Arrays.Sort of Points

I have this code :

import java.awt.Point;
import java.util.Arrays;

public class Haupt {

    // creates an array of anz Point objects
    public static Point[] generatePointArray(int anz) {
        Point[] pa = new Point[anz];
        for(int i = 0; i < anz; i++) {
            int px = (int) (Math.random() * 10);
            int py = (int) (Math.random() * 10);
            pa[i] = new Point(px,py);
        }
        return pa;
    }

    public static void main(String[] args) {
        Point[] pointArray = generatePointArray(15);

        Arrays.sort(pointArray);


        for(int i = 0 ;  i < pointArray.length; i++) {
            System.out.println("Point: "+pointArray[i] +
            " has distance "+pointArray[i].distance(0,0)+
            " from origin");
        }
    }
}

And as you may see I want to sort a point Array, therefore I wrote (nearly) a comparable :

import java.awt.Point;

public class MyPoint extends Point implements Comparable {
    public int compareTo(Object o)
    {
        Point p = (Point) o;


        if () {
            return -1;
        }
        if () {
            return 1;
            }
        return 0;
    }

}

What do I need to write inside the if() clause?

Edit: From the comments

The condition would be that I look after the value of the distance between the point(0,0) and Point (x,y) (If this is even possible

like image 941
Altin Avatar asked Oct 27 '25 05:10

Altin


2 Answers

Implementing the compareTo method depends entirely on how you want to sort these points. One plausible way to do so is by their X and Y coordinates:

public class MyPoint extends Point implements Comparable<MyPoint> {
    public int compareTo(MyPoint o) {
        int retVal = Double.compare(getX(), o.getX());
        if (retVal != 0) {
            return retVal;
        }
        return Double.compare(getY(), o.getY());
    }
}

Alternatively, instead of creating your own class that implements the Comparable interface, you could use a custom Comparator. With Java 8's enhancements, it would even be quite elegant:

Arrays.sort(
    pointArray, 
    Comparator.comparing(Point::getX).thenComparing(Point::getY)
);

EDIT:
The comments added a suggestion to sort the points by their distance from the origin (0, 0). This is also easily doable with both mechanisms. The distance of a point from the origin is defined as sqrt(x*x + y*y). Since sqrt is a monotonic transformation that does not affect the ordering, it can be omitted for a slight performance gain.

As Comparaable:

public class MyPoint extends Point implements Comparable<MyPoint> {
    public int compareTo(MyPoint o) {
        return Long.compare(getCompareKey(), o.getCompareKey());
    }

    private long getCompareKey() {
        return (getX() * getX()) + (getY() * getY());
    }
}

With a custom Comparator:

Arrays.sort(
    pointArray, 
    Comparator.comparing(p -> (p.getX() * p.getX()) + (p.getY() * p.getY())
);
like image 142
Mureinik Avatar answered Oct 29 '25 20:10

Mureinik


You can calculate the distance from origin using a private method in your class as:

private int distanceFromOrigin(Point point) {
    return (int) Math.sqrt(Math.pow(point.getX(), 2) + Math.pow(point.getY(), 2));
}

Then the compareTo method could be modified to include comparison between the distance of two Points as :

public int compareTo(Object o) {
    Point p = (Point) o;
    if (distanceFromOrigin(p) > distanceFromOrigin(this)) {
        return -1;
    }
    if (distanceFromOrigin(p) < distanceFromOrigin(this)) {
        return 1;
    }
    return 0;
}
like image 28
Naman Avatar answered Oct 29 '25 20:10

Naman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!