In my PriorityQueue I have 2 types of customers, VIP and regular. I want to serve VIP first, then regular.
If CustomerID < 100 it is considered to be VIP.
If a customer is VIP he goes at the end of VIP part of the queue
If a customer is regular he goes at the end of the entire queue.
In other words, I want to sort by boolean VIP value, while preserving the order in which customers came in.
Here's my Order class
public class Order implements Comparable<Order> {
private final int customerID;
private final int amount;
private final boolean vip_status;
public Order(int customerID, int amount) {
this.customerID = customerID;
this.amount = amount;
this.vip_status = customerID < 100 ? true : false;
}
@Override
public int compareTo(Order o) {
if (vip_status && !o.vip_status) {
return -1;
}
if (!vip_status && o.vip_status)
return 1;
return 0;
}
public int getCustomerID() {
return customerID;
}
public int getAmount() {
return amount;
}
public boolean isVip_status() {
return vip_status;
}
}
Here's my attempt to fill the queue:
import java.util.PriorityQueue;
public class MyPriorityQueue {
public static void main(String[] args) {
PriorityQueue<Order> queue = new PriorityQueue<>();
Order o1 = new Order(1, 50);
Order o2 = new Order(5, 30);
Order o3 = new Order(4, 10);
Order o4 = new Order(150, 5);
Order o5 = new Order(2, 5);
Order o6 = new Order(200, 5);
queue.add(o1);
queue.add(o2);
queue.add(o3);
queue.add(o4);
queue.add(o5);
queue.add(o6);
while(!queue.isEmpty()){
Order s = queue.poll();
System.out.printf("VIP Status: %s CustomerID: %s Amount: %s%n",
s.isVip_status(), s.getCustomerID(), s.getAmount());
}
}
}
RESULT that I'm getting (which is wrong):
VIP Status: true CustomerID: 1 Amount: 50
VIP Status: true CustomerID: 5 Amount: 30
VIP Status: true CustomerID: 2 Amount: 5
VIP Status: true CustomerID: 4 Amount: 10
VIP Status: false CustomerID: 150 Amount: 5
VIP Status: false CustomerID: 200 Amount: 5
This is what I expected to see (CustomerID 2 and 4 should be in the same order they came in):
VIP Status: true CustomerID: 1 Amount: 50
VIP Status: true CustomerID: 5 Amount: 30
VIP Status: true CustomerID: 4 Amount: 10
VIP Status: true CustomerID: 2 Amount: 5
VIP Status: false CustomerID: 150 Amount: 5
VIP Status: false CustomerID: 200 Amount: 5
UPDATE: I don't want sort by any other column except VIP. I don't want add "date" because it feels like a hack, rather than understanding how Java works.
PriorityQueue. comparator() method shares an important function of setting and returning the comparator that can be used to order the elements in a PriorityQueue. The method returns a null value if the queue follows the natural ordering pattern of the elements.
Since PriorityQueue is not thread-safe, java provides PriorityBlockingQueue class that implements the BlockingQueue interface to use in a java multithreading environment. The queue retrieval operations poll, remove, peek, and element access the element at the head of the queue.
A priority queue in Java is a special type of queue wherein all the elements are ordered as per their natural ordering or based on a custom Comparator supplied at the time of creation.
It appears that the PriorityQueue
class that java comes with out of the box feels free to reorder items if they compare as equal to each other.
(This is not "how java works", it is just a little perversion on behalf of a certain class that comes with the Java Runtime.)
So, here is something that will probably work:
Introduce a new OrderPlacement
class, containing a) an Order
and b) an int priority
.
In your PriorityQueue
add OrderPlacement
objects instead of Order
objects.
When you create a new OrderPlacement
object, issue a new priority
for it, by incrementing a counter.
Then, your OrderPlacement
object can have a compareTo()
method that looks like this:
@Override
public int compareTo( OrderPlacement o )
{
int d = -Boolean.compare( order.vip_status, o.order.vip_status );
if( d != 0 )
return d;
return Integer.compare( priority, o.priority );
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With