Priority Queue in Java - Tutorial with Examples

Oct 26, 2019 · 5 mins read

PriorityQueue is a built-in Java collection. In this tutorial, we’ll first review what a priority queues are, and then how to work with priority queues in Java. Let’s go.

What is a Priority Queue?

Let’s start by looking at plain old queues.

A queue is an efficient data-structure (collection) for storing a number of objects. The objects can be added in any arbitrary order and the queue remembers and keeps the order in which they were added. It supports retrieving elements only from its head or tail, which means you can only remove by the very first element you inserted into the queue (or the very last one.) Queues are often used to distribute work to a pool of workers. They act as a buffer between producers who are producing work at a high rate, and a limited pool of workers who are carrying out the work. For example, ThreadPool library in Java uses a queue to hold tasks submitted to it and transfers them to worker threads when they become available.

In many use cases, the default order of the queue (first-in-first-out) is sufficient. If you’re submitting jobs or tasks to a ThreadPool that are all the same, it is often desirable to process them in the same order in which they were submitted. But there are times when you’d want to process a category of high-priority tasks before low-priority ones. Suppose, you’re receiving online orders from your users and storing them in a queue to be processed by available workers. With a vanilla queue, the orders will be processed in the order in which they arrived. Now imagine that you want to expedite orders from premium customers and process them first over regular customers. A regular queue won’t help you with this.

Enter priority queues. They are just like regular queues with one important difference: each element in the queue has a priority attached to it. Elements can be pulled in the order of priority. To store elements, a priority queue uses a data structure called binary heap. A binary heap is a self-organizing binary tree which adjusts itself each time elements are added or removed from it. In the case of min-heap, the smallest element (1) is always kept at the very top regardless of the order in which it was inserted.

Min_Heap

It is important to call out that priority queues (binary heaps) do not store elements in absolute sorted order necessarily. It imposes semi-ordering for efficiency in terms of speed of insertion and retrieval. I’ll show this with an example by iterating through a priority queue.

For More Information on priority queues, read the CodeAhoy free book on priority queues.

Priority Queues in Java

A PriorityQueue is a type of queue which allows Java developers to insert elements in arbitrary order but retrieve them in a specific (sorted) order. The elements of the priority queue are ordered using a Comparator provided when the queue was created. Let’s look at a complete example.

package com.codeahoy.tutorial.datastructures;

import java.util.PriorityQueue;

public class PriorityQueueExample {

    public static void main(String[] args) {

        // Create a PriorityQueue that sorts elements
        // by their natural ordering
        PriorityQueue<Integer> pq = new PriorityQueue<>();

        // Let's add some elements to the PriorityQueue
        Integer [] elements = new Integer[]{8, 100, 98, 10, 2,
                15, 45, 25, 76, 3, 9, 1, 63, };

        for (int e: elements) {
            pq.add(e);
        }

        // Let's iterate through the elements to see they
        // are not necessarily stored in sorted order
        System.out.print("Print by Iterating: ");
        for(int e: pq) {
            System.out.print(e + " ");
        }

        System.out.println();
        System.out.print("Print by Retrieval: ");

        // Let's remove elements one by one
        while (!pq.isEmpty()) {
            System.out.print(pq.remove() + " ");
        }
    }
}

Output

Print by Iterating: 1 3 2 25 8 15 45 100 76 10 9 98 63 
Print by Retrieval: 1 2 3 8 9 10 15 25 45 63 76 98 100 

In the example above, you can see that I added a few integers to the queue in arbitrary order. Then I iterated through the queue and printed the elements. Here you can see that the elements are not stored in a sorted order. This is because binary heap only guarantees semi-ordering as discussed above: elements in the higher nodes are greater (or less) than than the elements in lower nodes. For example in a max-heap, parents are always greater than their children, as can be seen in the image below. Unlike Binary Search Trees, heaps don’t maintains absolute left-to-right ordering.

Max_Heap

PriorityBlocking Queue

PriorityBlockingQueue is a cousin of PriorityQueue in Java. It supports all the features of PriorityQueue and adds support for blocking operations. A blocking queue allow workers to ‘block’ or ‘wait’ if the queue is empty. They remain in the blocked state until new tasks arrive. Blocking queues are very convenient when building worker pools and are widely used by developers.

That’s all! In this post, we learned about priority queues and binary heap which it uses under the hood. If you need a refresher or more in-depth look at the heap data structure, I highly recommend that you watch the following video which does a pretty good job of covering this topic.

Image credits: By Ermishin - Own work, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=12251273

#java #boost

You May Also Enjoy


If you like this post, please share using the buttons above. It will help CodeAhoy grow and add new content. Thank you!