Search code examples
javasortingkey-valuecomparatorpriority-queue

Maintaining a PriorityQueue of Pairs such that it's elements are sorted based on the two fields of the Pair class


I have two arrays X & Y from which I'll creating Pairs of X[i] & Y[i]. Now I want to add them to a priorityQueue so that I can retrieve the largest Pair among the pairs currently available in the queue. And from largest I mean Pair with largest 'X' and if there are multiple equal larger 'X', then priority is given to 'Y'. I've tried 3 ways so far but none of them are working.

// 1] Using Lambda Operator
public static void main(String[] args)
{
    PriorityQueue<Pair> pTq = new PriorityQueue<>((x, y) -> (x.X == y.X) ? x.Y-y.Y : x.X-y.X);
    int[] X = {1, 6, 4, 9, 13, 13, 5, 20, 7, 6};
    int[] Y = {2, 9, 13, 4, 8, 1, 16, 7, 5, 5};
    for (int i=0; i<10; i++)
        pTq.add(new Pair(X[i] , Y[i]));
    System.out.println( pTq );
}
// 2] Using Custom Comparator
public static void main(String[] args)
{
    PriorityQueue<Pair> pTq = new PriorityQueue<Pair>(Comparator.comparing(Pair::getX).thenComparing(Pair::getY));

    int[] X = {1, 6, 4, 9, 13, 13, 5, 20, 7, 6};
    int[] Y = {2, 9, 13, 4, 8, 1, 16, 7, 5, 5};
    for (int i=0; i<10; i++)
        pTq.add(new Pair(X[i] , Y[i]));
    System.out.println( pTq );
}
// 3] Again Custom Comparator
public static void main(String[] args)
{
    PriorityQueue<Pair> pTq = new PriorityQueue<>(new Comparator<Pair>()
    {
        @Override
        public int compare(Pair a, Pair b)
        {
            return (a.X == b.X) ? a.Y-b.Y : a.X-b.X;
        }
    });
    int[] X = {1, 6, 4, 9, 13, 13, 5, 20, 7, 6};
    int[] Y = {2, 9, 13, 4, 8, 1, 16, 7, 5, 5};
    for (int i=0; i<10; i++)
        pTq.add(new Pair(X[i] , Y[i]));
    System.out.println( pTq );
}
// Pair Class for all of the above
class Pair
{
    int X, Y;
    Pair (int x, int y)
    {
        X = x;
        Y = y;
    }
    int getX(){return X;}
    int getY(){return Y;}
    public String toString()
    {
        return ("("+X+" , "+Y+")");
    }
}

Desired result: [(1 , 2), (4 , 13), (5 , 16), (6 , 5), (6 , 9), (7 , 5), (9 , 4), (13 , 1), (13 , 8), (20 , 7)]

Actual result: [(1 , 2), (6 , 5), (4 , 13), (7 , 5), (6 , 9), (13 , 1), (5 , 16), (20 , 7), (9 , 4), (13 , 8)]

I know what I want to achieve here can be done with other data structures such as a List of Pairs with a custom comparator but I want to know what's the mistake here or what I'm missing here. Thanks.


Solution

  • Your priority queue has the elements in the right order already. You have been misled by the order it is printed - See PriorityQueue.toString wrong element order

    If you repeatedly call poll in a loop, you can verify the same.