BhauAutomation

Java Queue & PriorityQueue

Learn about Queue and PriorityQueue in Java, their usage, advantages, limitations, methods, and examples. Understand how queues manage data in FIFO order and how PriorityQueue handles priority-based ordering.

📘 Topic: Java Collections / Data Structures
Read time: 7 min
📊 Level: Intermediate
🔄 Focus: FIFO & Priority Ordering
📖 Overview

📋 Queue

A Queue in Java is a data structure that follows the FIFO (First In First Out) principle. Elements are inserted at the rear (end) and removed from the front (beginning).

Real-world example: A ticket counter line - first person to stand in line gets served first.

⭐ PriorityQueue

PriorityQueue is a special type of Queue where elements are ordered based on their priority rather than insertion order. By default, smaller values have higher priority (min-heap).

Real-world example: Hospital emergency room - critical patients are treated before those with minor injuries, regardless of arrival time.

🔧 Queue Methods

Important Queue Methods

Method Description Exception vs Special Value
add(E e) Inserts element into queue throws IllegalStateException if full
offer(E e) Inserts element into queue returns false if full
remove() Removes and returns head element throws NoSuchElementException if empty
poll() Removes and returns head element returns null if empty
element() Returns head element without removing throws NoSuchElementException if empty
peek() Returns head element without removing returns null if empty
📋 Queue

Queue in Java

🎯 Objectives of Using Queue

Queue is used to manage tasks in order of arrival, implement scheduling algorithms (FCFS), store elements for sequential processing, and handle buffering in producer-consumer scenarios.

✅ Advantages

Queues maintain the order of elements (FIFO), are simple to implement with Java Collections, support efficient insertion at the end and removal from the front, and are useful for buffering and task scheduling.

⚠️ Limitations

Queues have limited access—only front and rear elements are directly accessible. They are not suitable for random access/search operations (O(n) time). Performance may vary with large datasets, and some Queue implementations have capacity restrictions.

📋 Queue Process / Usage

To use Queue in Java, import java.util.Queue or java.util.LinkedList, create a Queue instance, use add()/offer() to insert elements, remove()/poll() to remove elements, and peek() to check the front element.

💻 Example

import java.util.*;

public class QueueExample {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();
        
        // Adding elements
        queue.add("First");
        queue.add("Second");
        queue.offer("Third");
        
        System.out.println("Queue: " + queue);
        System.out.println("Head element: " + queue.peek());
        System.out.println("Removed: " + queue.poll());
        System.out.println("Queue after removal: " + queue);
        
        // Iterating through queue
        for (String item : queue) {
            System.out.println("Processing: " + item);
        }
    }
}
⭐ PriorityQueue

PriorityQueue in Java

🎯 Objectives of PriorityQueue

PriorityQueue is used to manage tasks according to priority, handle urgent tasks first, implement priority-based scheduling algorithms, and ensure that higher-priority elements are processed before lower-priority ones.

✅ Advantages

PriorityQueue automatically orders elements by priority (min-heap by default), is useful in simulations, scheduling systems, and task management, allows efficient retrieval of the highest-priority element (O(1) for peek, O(log n) for add/poll).

⚠️ Limitations

PriorityQueue does not allow direct access to arbitrary elements (no indexing), does not maintain insertion order for elements with the same priority (not stable), and performance may degrade with large data sets if comparator is complex. Also, PriorityQueue is not thread-safe.

📋 PriorityQueue Process

To use PriorityQueue, import java.util.PriorityQueue, create an instance, add elements using add()/offer() (automatically ordered by priority), retrieve head with peek(), and remove head with poll(). For custom ordering, provide a Comparator in the constructor.

💻 Example

import java.util.*;

public class PriorityQueueExample {
    public static void main(String[] args) {
        // Natural ordering (min-heap)
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        pq.add(30);
        pq.add(10);
        pq.add(20);
        pq.add(5);
        
        System.out.println("PriorityQueue: " + pq);
        System.out.println("Head element: " + pq.peek());
        
        while (!pq.isEmpty()) {
            System.out.println("Polled: " + pq.poll());
        }
        
        // PriorityQueue with custom comparator (max-heap)
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
        maxHeap.add(30);
        maxHeap.add(10);
        maxHeap.add(20);
        maxHeap.add(5);
        
        System.out.println("\nMax-Heap PriorityQueue:");
        while (!maxHeap.isEmpty()) {
            System.out.println("Polled: " + maxHeap.poll());
        }
        
        // PriorityQueue with custom objects
        PriorityQueue<String> pqStrings = new PriorityQueue<>((a,b) -> a.length() - b.length());
        pqStrings.add("Java");
        pqStrings.add("Python");
        pqStrings.add("C");
        pqStrings.add("JavaScript");
        
        System.out.println("\nStrings sorted by length:");
        while (!pqStrings.isEmpty()) {
            System.out.println("Polled: " + pqStrings.poll());
        }
    }
}
🎯 When to Use

Queue vs PriorityQueue: When to Use?

📋 Use Queue when:

✅ You need element processing in strict FIFO (First-In-First-Out) order
✅ Implementing simple task scheduling
✅ Handling producer-consumer problems
✅ Building buffers or caches
✅ Processing requests in arrival order

⭐ Use PriorityQueue when:

✅ Elements have natural ordering (e.g., numbers, strings)
✅ You need to process higher priority items first
✅ Implementing job scheduling with priorities
✅ Finding k smallest/largest elements efficiently
✅ Dijkstra's algorithm or Huffman coding

🏆 Best Practices

Best Practices for Queue & PriorityQueue

Choose the Queue type based on your ordering requirements (FIFO vs Priority)

Always check for empty queue using isEmpty() before calling removal methods

Use offer() and poll() instead of add() and remove() to avoid exceptions

For PriorityQueue with custom objects, implement Comparable or provide a Comparator

Use LinkedList for simple FIFO Queue implementations

For thread-safe operations, use BlockingQueue implementations like ArrayBlockingQueue or LinkedBlockingQueue