Reputation: 1
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
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
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