Tarık
Tarık

Reputation: 1

Priority Queue of user defined objects

I wanna create priority queue of objects according to their attributes. how can I compare the queue according to spesific attributes. for example if i type somewhere id, queue is designed for id. i have two different java file below. I wanna get all possible queues by comparing attributes of objects.

first

public class customers {

    int id;
    String name;
    int age;
    double money;
    public customers(int id, String name, int age, double money) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.money = money;
    }

public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }


}

main file starts now



import java.util.ArrayList;
import java.util.PriorityQueue;

public class draft {


    public static void main(String[] args) {

         PriorityQueue<customers> customerList= new PriorityQueue<>();
         customers customer1= new customers(0,"jack",30,180.5);
         customers customer2= new customers(1,"john",52,800.3);
         customers customer3= new customers(2,"alice", 41, 400.5);
         customerList.add(customer1);
         customerList.add(customer2);
         customerList.add(customer3);

        for (customers c:customerList
             ) {
            System.out.println(c.getId());
        }

    }


}

I want a simple solution like this. the code below is not valid but i can not understand complex codes. and i think there has to be a simple solution as this.

         PriorityQueue<customers> customerList= new PriorityQueue<>(customers.age);

i do not know if i explained the question. for example if i compare objects id, the queue should be object#0,object#1,object#2 in this order. if i compare objects's age the queue will be object#0, object#2,object#1

Upvotes: 0

Views: 2690

Answers (2)

GURU Shreyansh
GURU Shreyansh

Reputation: 909

Here are few ways to maintain a PriorityQueue based on any field of a particular class.
Below is an illustration to define a PriorityQueue sorted according to the field id (sorted in ascending order):

    public static void main(String[] args)
    {
        // Method 1] Using Custom Comparator
        PriorityQueue<Customers> pq1 = new PriorityQueue<Customers>(Comparator.comparing(Customers::getId));
        Customers customer1 = new Customers(0,"jack",30,180.5);
        Customers customer2 = new Customers(1,"john",52,800.3);
        Customers customer3 = new Customers(2,"alice", 41, 400.5);
        pq1.add(customer1);
        pq1.add(customer2);
        pq1.add(customer3);
        
        // Method 2] Using Lambda Operator
        PriorityQueue<Customers> pq2 = new PriorityQueue<>((x, y) -> x.id-y.id);
        //Method 3] Custom Comparator again
        PriorityQueue<Customers> pq3 = new PriorityQueue<>(new Comparator<Customers>()
        {
            @Override
            public int compare(Customers a, Customers b)
            {
                return a.id-b.id;
            }
        });
        pq2.addAll(pq1);
        pq3.addAll(pq1);
        
        System.out.println(pq1);
        System.out.println(pq2);
        System.out.println(pq3);
    }

Output:
[(0 , jack , 30 , 180.5), (1 , john , 52 , 800.3), (2 , alice , 41 , 400.5)]
[(0 , jack , 30 , 180.5), (1 , john , 52 , 800.3), (2 , alice , 41 , 400.5)]
[(0 , jack , 30 , 180.5), (1 , john , 52 , 800.3), (2 , alice , 41 , 400.5)]
Similarly you can design other queues based on any field of your choice.

To maintain the priority queue in reverse order (Decreasing/Descending order), we need to reverse the orders in the comprators like:

PriorityQueue<Customers> pq2 = new PriorityQueue<>((x, y) -> y.id-x.id);

Please note, for ascending it was: (x, y) -> x.id-y.id
for descending it will be: (x, y) -> y.id-x.id
Using custom Comparator:

    PriorityQueue<Customers> pq3 = new PriorityQueue<>(new Comparator<Customers>()
    {
        @Override
        public int compare(Customers a, Customers b)
        {
            return b.id-a.id; // reversed
        }
    });

And if you want to sort the priority queue based on two fields, let say age & id in such a way that if multiple age's are equal, then priority is given to id.
You can achieve the above in the following ways:

    public static void main(String[] args)
    {
        // Method 1] Using Custom Comparator (Increasing order)
        PriorityQueue<Customers> pq1 = new PriorityQueue<Customers>(Comparator.comparing(Customers::getAge).thenComparing(Customers::getId));
        Customers customer1 = new Customers(0,"jack",30,180.5);
        Customers customer2 = new Customers(1,"john",52,800.3);
        Customers customer3 = new Customers(2,"alice", 41, 400.5);
        pq1.add(customer1);
        pq1.add(customer2);
        pq1.add(customer3);
        
        // Method 2] Using Lambda Operator (Increasing order)
        PriorityQueue<Customers> pq2 = new PriorityQueue<>((x, y) -> (x.age == y.age) ? x.id-y.id : x.age-y.age);
        //Method 3] Custom Comparator again (Reverse order)
        PriorityQueue<Customers> pq3 = new PriorityQueue<>(new Comparator<Customers>()
        {
            @Override
            public int compare(Customers a, Customers b)
            {
                return (a.age == b.age) ? b.id-a.id : b.age-a.age;
            }
        });
        pq2.addAll(pq1);
        pq3.addAll(pq1);
        
        System.out.println(pq1);
        System.out.println(pq2);
        System.out.println(pq3);
    }

For sorting based on age & money, few modifications are required as money is of double dataType. Below is how you can achieve the desired:

    PriorityQueue<Customers> pq1 = new PriorityQueue<Customers>(Comparator.comparing(Customers::getAge).thenComparing(Customers::getMoney));
    PriorityQueue<Customers> pq2 = new PriorityQueue<>((x, y) -> (x.age == y.age) ? Double.compare(x.money,y.money) : x.age-y.age);
    PriorityQueue<Customers> pq3 = new PriorityQueue<>(new Comparator<Customers>()
    {   @Override
        public int compare(Customers a, Customers b)
        {
            return (a.age == b.age) ? Double.compare(a.money,b.money) : a.age-b.age;
        }
    });

Use the poll method to verify the order of elements in the priorityQueue.
All the implementations are easy to understand. But if you are having a tough time understanding it, please reach out.

Upvotes: 1

njari
njari

Reputation: 192

The way to do this would be to use multiple Comparator classes. Comparator gives us a way to define HOW we want our objects to be compared to each other - in your case, it could be id,age etc.

public class Comparator<Customer> CustomerAgeComparator implements Comparator<Customer>() {

    public int compare(Customer user1, Customer user2) {

        int userPoints1 = user1.getAge();
        int userPoints2 = user2.getAge();
        if (userPoints1 == userPoints2)
        return 0;
        else if (userPoints1 > userPoints2)
        return 1;
        else
        return -1;
    }
 };

The above comparator will sort customers in descending order of age. Then you need to pass this information to your Priority Queue somehow. Luckily PriorityQueue has a constructor that allows one to do just that. Call it in the following manner :

PriorityQueue oldestCustomerFirst = PriorityQueue<String>(new CustomerAgeComparator);

Upvotes: 0

Related Questions