Search code examples
javasorting2dcomparatorpoints

How to compare (x,y) points for sorting, where x is always first


I'm using Java Comparator to compare location objects with points (x,y).

I need to be able to compare two points to retrieve a positive or negative integer that will allow me to sort (x,y) points, where x-values are sorted first, then y-values secondly. (If that makes sense...) For example, this:

(3,4) (2,5) (1,1) (1,3) (3,3)

Becomes this:

(1,1) (1,3) (2,5) (3,3) (3,4)

One way I've thought to do it is essentially by giving the x-value large precedence by multiplying it by a large number like 1000. Like so: Comparing (3,3) and (1,1):

int x_multiplier = 1000;
int value1 = (p1.x * x_multiplier ) + p1.y; // = 3 * 1000 + 3 = 3003
int value2 = (p2.x * x_multiplier ) + p2.y; // = 1 * 1000 + 1 = 1001
return value1-value2; // = 2002. Value1 is greater, thus p1 be later in list.

This works, but the issue with this is if the Y-value should ever be equal to or greater than the x_multiplier, then this breaks down (because that y-value is now equal to 1 x-value... again, if that makes sense.)

// Comparing p1 = (2,0) & p2 = (1,18)
int x_multiplier = 10;
int value1 = (p1.x * x_multiplier ) + p1.y; // = 2 * 10 + 0  = 20
int value2 = (p2.x * x_multiplier ) + p2.y; // = 1 * 10 + 18 = 28
return value1-value2; // = -8, value2 is greater, and thus p2 will be later in the list. However, we know by looking at the points that p2 should come first.

I don't really even know how to search for this, so if there are answers out there I couldn't find them.


Solution

  • import java.util.*;
    
    class Tuple {
        public int x, y;
    
        Tuple(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        @Override
        public String toString() {
            return "(" + x + ", " + y + ") ";
        }
    }
    
    public class coord {
        public static void main(String[] args) {
            LinkedList<Tuple> list = new LinkedList<Tuple>();
            list.add(new Tuple(3,4));
            list.add(new Tuple(2,5));
            list.add(new Tuple(1,1));
            list.add(new Tuple(1,3));
            list.add(new Tuple(3,3));
            for (Tuple t: list) {
                System.out.print(t);
            }
            Collections.sort(list, (Tuple t1, Tuple t2) -> {
                int result = Integer.compare(t1.x, t2.x);
                if (result == 0 ) result = Integer.compare(t1.y, t2.y);
                return result;
            });
            System.out.println("Sorted List: ");
            for (Tuple t: list) {
                System.out.print(t);
            }
        }
    }