What’s New ?

The Top 10 favtutor Features You Might Have Overlooked

Read More

Java Priority Queue (With Examples)

  • Oct 14, 2023
  • 12 Minutes Read
  • Why Trust Us
    We uphold a strict editorial policy that emphasizes factual accuracy, relevance, and impartiality. Our content is crafted by top technical writers with deep knowledge in the fields of computer science and data science, ensuring each piece is meticulously reviewed by a team of seasoned editors to guarantee compliance with the highest standards in educational content creation and publishing.
  • By Nihal Mahansaria
Java Priority Queue (With Examples)

Welcome to our comprehensive guide on Java Priority Queue! In this article, we will explore the ins and outs of the priority queue data structure in Java. Whether you are a beginner or an experienced Java developer, this guide is designed to provide you with a deep understanding of priority queues and their implementation in Java. So let's dive in and explore the fascinating world of priority queues! 

What is a Priority Queue?

Before we dive into the specifics of Java Priority Queue, let's first understand what a priority queue is. A priority queue is a data structure that allows elements to be processed based on their priority. While a normal queue follows the First-In-First-Out (FIFO) algorithm, a priority queue reorders the elements based on their priority. The element with the highest priority is processed first, regardless of the order in which it was added to the queue.

In a priority queue, elements are assigned a priority value, which determines their position in the queue. The element with the highest priority is always at the front of the queue and is the first to be processed. If two elements have the same priority, their order is determined by a tie-breaking mechanism, which can be arbitrary or based on additional criteria.

Priority queues have a wide range of applications, such as task scheduling, event processing, and resource allocation. In Java, the PriorityQueue class provides an implementation of the priority queue data structure, allowing you to easily manage and process elements based on their priority.

Priority Queue in Java

Introduction to Java Priority Queue

In Java, the java.util.PriorityQueue class provides an implementation of the priority queue data structure. It is an unbounded queue, meaning it can grow dynamically as elements are added to it. The elements in a priority queue are ordered according to their natural ordering or a custom comparator provided at the time of queue construction.

The PriorityQueue class is part of the Java Collections Framework and implements the Queue interface. It provides methods for adding, removing, and accessing elements in the queue, as well as other operations such as checking the size and determining the comparator used for ordering.

Java Priority Queue Implementation

Internally, the PriorityQueue class in Java is implemented using a priority heap. A priority heap is a complete binary tree where each node has a priority value associated with it. The elements in the priority queue are stored in this binary tree structure, with the highest priority element at the root of the tree.

The PriorityQueue class uses the priority heap to maintain the order of its elements. When an element is added to the queue, it is inserted into the appropriate position in the heap based on its priority. Similarly, when an element is removed from the queue, the highest priority element at the root of the heap is extracted.

The PriorityQueue class provides efficient operations for adding and removing elements, with a time complexity of O(log(n)) for both enqueue and dequeue operations. It also provides constant time retrieval of the highest priority element using the peek() method.

Creating a Priority Queue

Java Priority Queue can be created using different constructors provided by the PriorityQueue class. Let's take a look at the various ways to create a priority queue in Java.

Default Priority Queue

The default constructor of the PriorityQueue class creates a priority queue with the default initial capacity, which is 11. This constructor orders the elements in the queue based on their natural ordering. Here's an example:

PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
	

 

In the above example, we created a priority queue of integers using the default constructor. The elements in this priority queue will be ordered in ascending order.

Priority Queue with Custom Comparator

If you want to order the elements in the priority queue based on a custom ordering, you can provide a custom comparator to the constructor. A comparator is an object that defines the ordering of elements in a priority queue. Here's an example:

PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(Comparator.reverseOrder());

 

In the above example, we created a priority queue of integers with a custom comparator that orders the elements in reverse order, i.e., in descending order.

Priority Queue Operations

Once we have created a priority queue, we can perform various operations on it, such as adding elements, accessing elements, and removing elements. Let's explore these operations in detail.

Adding Elements to a Priority Queue

To add elements to a priority queue, we can use the add(E element) or offer(E element) methods. Both methods insert the specified element into the priority queue. If the queue is full, the add() method throws an exception, while the offer() method returns false.

priorityQueue.add(10);
priorityQueue.offer(20);

 

In the above example, we added the elements 10 and 20 to the priority queue using the add() and offer() methods, respectively.

Accessing Elements in a Priority Queue

To access the elements in a priority queue, we can use the peek() method. This method retrieves, but does not remove, the head of the queue, i.e., the element with the highest priority.

java

Integer element = priorityQueue.peek();

 

In the above example, we retrieved the element with the highest priority from the priority queue using the peek() method.

Removing Elements from a Priority Queue

To remove elements from a priority queue, we can use the poll() method. This method retrieves and removes the head of the queue, i.e., the element with the highest priority. If the queue is empty, the poll() method returns null.

Integer element = priorityQueue.poll();

 

In the above example, we removed the element with the highest priority from the priority queue using the poll() method.

Priority Queue Ordering

Java Priority Queue orders its elements based on their priority. By default, the elements are ordered in ascending order, with the highest priority element at the head of the queue. However, you can also specify a custom ordering using a comparator.

Natural Ordering

When a priority queue is created without a custom comparator, it orders its elements based on their natural ordering. The natural ordering is defined by the Comparable interface implemented by the elements. For example, if the priority queue contains integers, the elements will be ordered in ascending order.

PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();

 

In the above example, the priority queue orders the integers in ascending order based on their natural ordering.

Custom Ordering

If you want to order the elements in the priority queue based on a custom ordering, you can provide a custom comparator to the constructor. A comparator is an object that compares two elements and determines their order. You can define your own comparator by implementing the Comparator interface.

Here's an example of creating a priority queue with a custom comparator that orders strings based on their length:

PriorityQueue<String> priorityQueue = new PriorityQueue<>(Comparator.comparingInt(String::length));

 

In the above example, the priority queue orders the strings based on their length, with the shortest string having the highest priority.

Java Priority Queue Methods

The PriorityQueue class provides various methods to perform operations on the priority queue. Let's explore some of the commonly used methods.

add(E element)

The add(E element) method inserts the specified element into the priority queue. If the queue is full, it throws an exception.

priorityQueue.add(element);

 

comparator()

The comparator() method returns the comparator used to order the elements in the priority queue. If no comparator was specified and the queue is sorted according to the natural ordering of its elements, the method returns null.

Comparator<Integer> comparator = priorityQueue.comparator();

 

contains(Object o)

The contains(Object o) method returns true if the priority queue contains the specified element.

boolean containsElement = priorityQueue.contains(element);

 

offer(E element)

The offer(E element) method is similar to the add() method and adds an element to the priority queue. If the operation fails to add the element, it returns false.

boolean added = priorityQueue.offer(element);

 

peek()

The peek() method retrieves the head of the priority queue, i.e., the element with the highest priority, without removing it from the queue.

E element = priorityQueue.peek();


poll()

The poll() method retrieves and removes the head of the priority queue, i.e., the element with the highest priority. If the queue is empty, it returns null.

E element = priorityQueue.poll();

 

remove(Object o)

The remove(Object o) method removes the specified element from the priority queue if it is present.

boolean removed = priorityQueue.remove(element);

 

size()

The size() method returns the number of elements in the priority queue.

int size = priorityQueue.size();

 

Java Priority Queue Example

Now that we have covered the basics of Java Priority Queue, let's walk through some examples to see how they can be used in practice.

Example 1: Task Prioritization

Consider a scenario where you have a set of tasks with different priorities, and you want to process them in the order of their priority. You can use a priority queue to manage the tasks and process them accordingly.

PriorityQueue<String> taskQueue = new PriorityQueue<>();
taskQueue.add("High priority task");
taskQueue.add("Medium priority task");
taskQueue.add("Low priority task");

while (!taskQueue.isEmpty()) {
String task = taskQueue.poll();
System.out.println("Processing task: " + task);
}

 

In the above example, we created a priority queue to manage tasks with different priorities. We added tasks to the queue and then processed them in the order of their priority using the poll() method.

Example 2: Event Scheduling

Let's consider another example where you want to schedule events based on their start time. You can use a priority queue to manage the events and process them in the order of their start time.

class Event {
private String name;
private LocalDateTime startTime;

public Event(String name, LocalDateTime startTime) {
this.name = name;
this.startTime = startTime;
}

public String getName() {
return name;
}

public LocalDateTime getStartTime() {
return startTime;
}
}

PriorityQueue<Event> eventQueue = new PriorityQueue<>(Comparator.comparing(Event::getStartTime));
eventQueue.add(new Event("Event 1", LocalDateTime.of(2022, 1, 1, 10, 0)));
eventQueue.add(new Event("Event 2", LocalDateTime.of(2022, 1, 1, 12, 0)));
eventQueue.add(new Event("Event 3", LocalDateTime.of(2022, 1, 1, 11, 0)));

while (!eventQueue.isEmpty()) {
Event event = eventQueue.poll();
System.out.println("Scheduled event: " + event.getName());
}

 

In the above example, we created a priority queue to manage events based on their start time. We added events to the queue and then scheduled them in the order of their start time using the custom comparator.

Java Priority Queue vs. Queue

It's important to note that while a priority queue is a type of queue, there are some key differences between a priority queue and a normal queue.

In a normal queue, elements are processed in the order they were added, following the First-In-First-Out (FIFO) principle. However, in a priority queue, elements are processed based on their priority, which is determined by a comparison mechanism.

While both types of queues have their uses, it's essential to choose the appropriate one based on the specific requirements of your application. If you need to process elements based on their priority, a priority queue is the way to go.

Java Priority Blocking Queue

In a multi-threaded environment, it's important to ensure thread safety when using a priority queue. The PriorityQueue class in Java is not thread-safe. However, Java provides the PriorityBlockingQueue class, which is an implementation of the BlockingQueue interface and offers thread-safe operations on a priority queue.

The PriorityBlockingQueue class provides all the functionality of a priority queue while ensuring thread safety. It allows multiple threads to access and modify the queue concurrently without the need for external synchronization.

To use a PriorityBlockingQueue, you can create an instance of it and use the same methods as a regular priority queue.

PriorityBlockingQueue<Integer> priorityQueue = new PriorityBlockingQueue<>();
priorityQueue.add(10);
priorityQueue.add(20);

Integer element = priorityQueue.poll();

 

In the above example, we created a PriorityBlockingQueue and added elements to it. We then used the poll() method to retrieve and remove the head of the queue.

Conclusion

In this comprehensive guide, we explored the Java Priority Queue and its implementation in detail. We learned that a priority queue allows elements to be processed based on their priority, and Java provides the PriorityQueue class for this purpose. We covered various aspects of the priority queue, such as creating a priority queue, adding and removing elements, and accessing elements. We also discussed priority queue ordering, methods, and provided examples to demonstrate its usage.

By leveraging the power of Java Priority Queue, you can efficiently manage and process elements based on their priority in a wide range of applications. Whether you need to prioritize tasks, schedule events, or perform other operations that require ordering based on priority, Java Priority Queue has got you covered.

So go ahead, explore the world of priority queues in Java, and unlock the potential of efficient and organized processing of your data!

FavTutor - 24x7 Live Coding Help from Expert Tutors!

About The Author
Nihal Mahansaria
As a computer science student with a passion for technology and a drive to learn, I have developed a diverse set of skills in web development, machine learning, and technical content writing. With experience in multiple front-end and back-end frameworks, including Flask and Python, I am able to create scalable and efficient web applications.