We know that Queue follows First-In-First-Out model but sometimes we need to process the objects in the queue based on the priority. For example, let’s say we have an application that generates stocks reports for daily trading session and it processes a lot of data and takes time to process it. So customers are sending request to the application that is actually getting queued but we want to process premium customers first and standard customers after them. So in this casePriorityQueue implementation in java can be really helpful.
PriorityQueue
class was introduced in Java 1.5 and part of
Java Collections Framework. PriorityQueue is an unbounded queue based on a priority heap and the elements of the priority queue are ordered by default in natural order or we can provide a
Comparator for ordering at the time of instantiation of queue.
PriorityQueue doesn’t allow
null values and we can’t create PriorityQueue of Objects that are non-comparable, for example any custom classes we have. We use
java Comparable and Comparator interfaces for sorting Objects and PriorityQueue use them for priority processing of it’s elements.
The head of the priority queue is the least element based on the natural ordering or comparator based ordering, if there are multiple objects with same ordering, then it can poll any one of them randomly. When we poll the queue, it returns the head object from the queue.
PriorityQueue size is unbounded but we can specify the initial capacity at the time of it’s creation. When we add elements to the priority queue, it’s capacity grows automatically.
PriorityQueue implementation provides O(log(n)) time for enqueing and dequeing method. Let’s see an example of PriorityQueue for natural ordering as well as with Comparator.
We have our custom class Customer
that doesn’t provide any type of ordering, so when we will try to use it with PriorityQueue we should provide a comparator object for that.
01 | package com.journaldev.collections; |
03 | public class Customer { |
08 | public Customer( int i, String n){ |
17 | public String getName() { |
Here is our final test code that shows how to use PriorityQueue.
01 | package com.journaldev.collections; |
03 | import java.util.Comparator; |
04 | import java.util.PriorityQueue; |
05 | import java.util.Queue; |
06 | import java.util.Random; |
08 | public class PriorityQueueExample { |
10 | public static void main(String[] args) { |
13 | Queue<Integer> integerPriorityQueue = new PriorityQueue<>( 7 ); |
14 | Random rand = new Random(); |
16 | integerPriorityQueue.add( new Integer(rand.nextInt( 100 ))); |
19 | Integer in = integerPriorityQueue.poll(); |
20 | System.out.println( "Processing Integer:" +in); |
24 | Queue<Customer> customerPriorityQueue = new PriorityQueue<>( 7 , idComparator); |
25 | addDataToQueue(customerPriorityQueue); |
27 | pollDataFromQueue(customerPriorityQueue); |
32 | public static Comparator<Customer> idComparator = new Comparator<Customer>(){ |
35 | public int compare(Customer c1, Customer c2) { |
36 | return ( int ) (c1.getId() - c2.getId()); |
41 | private static void addDataToQueue(Queue<Customer> customerPriorityQueue) { |
42 | Random rand = new Random(); |
43 | for ( int i= 0 ; i< 7 ; i++){ |
44 | int id = rand.nextInt( 100 ); |
45 | customerPriorityQueue.add( new Customer(id, "Customer- " +id)); |
50 | private static void pollDataFromQueue(Queue<Customer> customerPriorityQueue) { |
52 | Customer cust = customerPriorityQueue.poll(); |
53 | if (cust == null ) break ; |
54 | System.out.println( "Processing Customer with ID=" +cust.getId()); |
Notice that I am using
java anonymous class for implementing Comparator interface and creating our id based comparator.
When I run above test program, I get following output:
08 | Processing Customer with ID=6 |
09 | Processing Customer with ID=20 |
10 | Processing Customer with ID=24 |
11 | Processing Customer with ID=28 |
12 | Processing Customer with ID=29 |
13 | Processing Customer with ID=82 |
14 | Processing Customer with ID=96 |
From output it’s clear that least element was at head and got polled first. If we won’t provide comparator while creatingcustomerPriorityQueue
, it will throw ClassCastException at runtime.
1 | Exception in thread "main" java.lang.ClassCastException: com.journaldev.collections.Customer cannot be cast to java.lang.Comparable |
2 | at java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:633) |
3 | at java.util.PriorityQueue.siftUp(PriorityQueue.java:629) |
4 | at java.util.PriorityQueue.offer(PriorityQueue.java:329) |
5 | at java.util.PriorityQueue.add(PriorityQueue.java:306) |
6 | at com.journaldev.collections.PriorityQueueExample.addDataToQueue(PriorityQueueExample.java:45) |
7 | at com.journaldev.collections.PriorityQueueExample.main(PriorityQueueExample.java:25) |
No comments :
Post a Comment