Home/Java/Queue in Java

Queue in Java

Learn about First-In-First-Out (FIFO) collections

💡 Think of a Queue like a line at a store - the first person who gets in line is the first person to be served! People join at the back of the line and leave from the front. It's fair because everyone waits their turn in order!

🚶 What is a Queue?

A Queue is a collection designed for holding elements before processing. It follows the FIFO (First-In-First-Out) principle. Elements are added at the tail (rear) and removed from the head (front). Think of it like a waiting line!

BasicQueue.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import java.util.LinkedList;
import java.util.Queue;
public class BasicQueue {
public static void main(String[] args) {
// Creating a Queue using LinkedList
Queue<String> queue = new LinkedList<>();
// Adding elements to the queue (at the tail)
queue.offer("First");
queue.offer("Second");
queue.offer("Third");
queue.offer("Fourth");
System.out.println("Queue: " + queue);
// [First, Second, Third, Fourth]
// Peek at the front element (without removing)
String front = queue.peek();
System.out.println("Front element: " + front); // First
System.out.println("Queue after peek: " + queue); // Unchanged
// Remove and get the front element
String removed1 = queue.poll(); // Removes "First"
System.out.println("Removed: " + removed1);
System.out.println("Queue after poll: " + queue);
// [Second, Third, Fourth]
// Continue removing
queue.poll(); // Removes "Second"
System.out.println("After second poll: " + queue);
// [Third, Fourth]
// Size and empty check
System.out.println("\nQueue size: " + queue.size());
System.out.println("Is empty? " + queue.isEmpty());
// Poll from empty queue returns null
queue.poll(); // Removes "Third"
queue.poll(); // Removes "Fourth"
String fromEmpty = queue.poll(); // Queue is now empty
System.out.println("\nPolling empty queue: " + fromEmpty); // null
}
}

🔍 📋 Types of Queues

Java provides different Queue implementations for different scenarios:

1

LinkedList

Most common Queue implementation, allows null elements, implements both Queue and Deque

2

PriorityQueue

Elements ordered by priority (natural order or comparator), not strictly FIFO

3

ArrayDeque

Faster than LinkedList, no null elements, implements Deque interface

4

PriorityBlockingQueue

Thread-safe version of PriorityQueue for concurrent programming

PriorityQueueExample.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.util.PriorityQueue;
import java.util.Queue;
public class PriorityQueueExample {
public static void main(String[] args) {
// PriorityQueue orders elements by natural order (or comparator)
Queue<Integer> priorityQueue = new PriorityQueue<>();
// Add elements in random order
priorityQueue.offer(5);
priorityQueue.offer(2);
priorityQueue.offer(8);
priorityQueue.offer(1);
priorityQueue.offer(3);
System.out.println("PriorityQueue: " + priorityQueue);
// NOTE: Internal order may look random, but poll() gives sorted order
// Elements come out in sorted order (lowest first)
System.out.println("\nRemoving elements in priority order:");
while (!priorityQueue.isEmpty()) {
System.out.println(priorityQueue.poll());
}
// Output: 1, 2, 3, 5, 8
// PriorityQueue with custom comparator (reverse order)
Queue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
maxHeap.offer(5);
maxHeap.offer(2);
maxHeap.offer(8);
maxHeap.offer(1);
System.out.println("\nMax heap (highest priority first):");
while (!maxHeap.isEmpty()) {
System.out.println(maxHeap.poll());
}
// Output: 8, 5, 2, 1
}
}

🖨️ Real-World Example: Printer Queue

PrinterQueue.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import java.util.LinkedList;
import java.util.Queue;
class PrintJob {
String documentName;
int pages;
public PrintJob(String documentName, int pages) {
this.documentName = documentName;
this.pages = pages;
}
@Override
public String toString() {
return documentName + " (" + pages + " pages)";
}
}
public class PrinterQueue {
private Queue<PrintJob> printQueue;
public PrinterQueue() {
this.printQueue = new LinkedList<>();
}
// Add print job to queue
public void addPrintJob(String documentName, int pages) {
PrintJob job = new PrintJob(documentName, pages);
printQueue.offer(job);
System.out.println("Added to queue: " + job);
}
// Process next print job
public void printNext() {
if (printQueue.isEmpty()) {
System.out.println("No documents in queue!");
return;
}
PrintJob job = printQueue.poll();
System.out.println("\nPrinting: " + job);
System.out.println("Remaining jobs: " + printQueue.size());
}
// View next job without printing
public void viewNext() {
PrintJob job = printQueue.peek();
if (job != null) {
System.out.println("Next in queue: " + job);
} else {
System.out.println("Queue is empty!");
}
}
// View all pending jobs
public void viewAllJobs() {
if (printQueue.isEmpty()) {
System.out.println("\nNo pending jobs");
return;
}
System.out.println("\n=== Print Queue ===");
int position = 1;
for (PrintJob job : printQueue) {
System.out.println(position++ + ". " + job);
}
System.out.println("Total jobs: " + printQueue.size());
}
public static void main(String[] args) {
PrinterQueue printer = new PrinterQueue();
// Add print jobs
printer.addPrintJob("Report.pdf", 10);
printer.addPrintJob("Presentation.pptx", 25);
printer.addPrintJob("Invoice.docx", 3);
printer.addPrintJob("Photo.jpg", 1);
// View all jobs
printer.viewAllJobs();
// View next job
printer.viewNext();
// Process jobs
printer.printNext();
printer.printNext();
// View remaining jobs
printer.viewAllJobs();
// Print remaining jobs
printer.printNext();
printer.printNext();
// Try to print when empty
printer.printNext();
}
}

⏰ Real-World Example: Task Scheduler

TaskScheduler.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import java.util.ArrayDeque;
import java.util.Deque;
class Task {
String name;
int estimatedMinutes;
public Task(String name, int estimatedMinutes) {
this.name = name;
this.estimatedMinutes = estimatedMinutes;
}
@Override
public String toString() {
return name + " (~" + estimatedMinutes + " min)";
}
}
public class TaskScheduler {
private Deque<Task> taskQueue;
public TaskScheduler() {
// Using ArrayDeque (faster than LinkedList)
this.taskQueue = new ArrayDeque<>();
}
// Add task to end of queue
public void addTask(String name, int minutes) {
Task task = new Task(name, minutes);
taskQueue.offerLast(task);
System.out.println("Scheduled: " + task);
}
// Add urgent task to front of queue
public void addUrgentTask(String name, int minutes) {
Task task = new Task(name, minutes);
taskQueue.offerFirst(task);
System.out.println("URGENT - Added to front: " + task);
}
// Complete next task
public void completeNextTask() {
if (taskQueue.isEmpty()) {
System.out.println("No tasks to complete!");
return;
}
Task task = taskQueue.pollFirst();
System.out.println("\nCompleted: " + task);
System.out.println("Remaining tasks: " + taskQueue.size());
}
// Remove last task (undo scheduling)
public void removeLastScheduled() {
Task task = taskQueue.pollLast();
if (task != null) {
System.out.println("Removed: " + task);
}
}
// View all tasks
public void viewTasks() {
if (taskQueue.isEmpty()) {
System.out.println("\nNo scheduled tasks");
return;
}
System.out.println("\n=== Task Schedule ===");
int totalMinutes = 0;
int position = 1;
for (Task task : taskQueue) {
System.out.println(position++ + ". " + task);
totalMinutes += task.estimatedMinutes;
}
System.out.println("\nTotal tasks: " + taskQueue.size());
System.out.println("Estimated time: " + totalMinutes + " minutes");
}
public static void main(String[] args) {
TaskScheduler scheduler = new TaskScheduler();
// Schedule normal tasks
scheduler.addTask("Write email", 15);
scheduler.addTask("Team meeting", 30);
scheduler.addTask("Code review", 45);
scheduler.addTask("Lunch break", 60);
// View schedule
scheduler.viewTasks();
// Urgent task comes in!
scheduler.addUrgentTask("Fix critical bug", 20);
// View updated schedule
scheduler.viewTasks();
// Complete tasks
scheduler.completeNextTask(); // Fix critical bug
scheduler.completeNextTask(); // Write email
// Cancel last task
scheduler.removeLastScheduled(); // Remove lunch break
// View final schedule
scheduler.viewTasks();
}
}

🏥 Real-World Example: Hospital Emergency Room

EmergencyRoom.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import java.util.PriorityQueue;
import java.util.Queue;
class Patient implements Comparable<Patient> {
String name;
int severity; // 1 = Critical, 2 = Serious, 3 = Moderate, 4 = Minor
public Patient(String name, int severity) {
this.name = name;
this.severity = severity;
}
// Lower severity number = higher priority
@Override
public int compareTo(Patient other) {
return Integer.compare(this.severity, other.severity);
}
@Override
public String toString() {
String level = switch (severity) {
case 1 -> "CRITICAL";
case 2 -> "SERIOUS";
case 3 -> "MODERATE";
default -> "MINOR";
};
return name + " [" + level + "]";
}
}
public class EmergencyRoom {
private Queue<Patient> waitingRoom;
public EmergencyRoom() {
this.waitingRoom = new PriorityQueue<>();
}
// Register patient
public void registerPatient(String name, int severity) {
Patient patient = new Patient(name, severity);
waitingRoom.offer(patient);
System.out.println("Registered: " + patient);
}
// Treat next patient (highest priority)
public void treatNextPatient() {
if (waitingRoom.isEmpty()) {
System.out.println("No patients waiting!");
return;
}
Patient patient = waitingRoom.poll();
System.out.println("\nTreating: " + patient);
System.out.println("Patients waiting: " + waitingRoom.size());
}
// View next patient
public void viewNext() {
Patient patient = waitingRoom.peek();
if (patient != null) {
System.out.println("Next patient: " + patient);
} else {
System.out.println("No patients waiting");
}
}
// View all waiting patients
public void viewAllPatients() {
if (waitingRoom.isEmpty()) {
System.out.println("\nNo patients waiting");
return;
}
System.out.println("\n=== Waiting Room ===");
// Create copy to preserve queue
Queue<Patient> copy = new PriorityQueue<>(waitingRoom);
int position = 1;
while (!copy.isEmpty()) {
System.out.println(position++ + ". " + copy.poll());
}
System.out.println("Total waiting: " + waitingRoom.size());
}
public static void main(String[] args) {
EmergencyRoom er = new EmergencyRoom();
// Patients arrive in random order
er.registerPatient("John (broken arm)", 3); // Moderate
er.registerPatient("Sarah (heart attack)", 1); // Critical!
er.registerPatient("Mike (flu)", 4); // Minor
er.registerPatient("Emma (car accident)", 2); // Serious
er.registerPatient("Tom (cut finger)", 4); // Minor
// View all patients (in priority order)
er.viewAllPatients();
// Treat patients - critical cases first!
System.out.println("\n--- Starting Treatment ---");
er.treatNextPatient(); // Sarah (critical)
er.treatNextPatient(); // Emma (serious)
er.treatNextPatient(); // John (moderate)
// View remaining
er.viewAllPatients();
// New critical patient arrives!
er.registerPatient("Alice (severe bleeding)", 1);
er.viewNext(); // Alice goes to front!
er.treatNextPatient(); // Alice
er.treatNextPatient(); // Mike
er.treatNextPatient(); // Tom
}
}

🔄 Queue Methods Comparison

QueueMethods.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import java.util.LinkedList;
import java.util.Queue;
public class QueueMethods {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
// ===== ADDING ELEMENTS =====
// add() - throws exception if fails (for bounded queues)
queue.add("A");
queue.add("B");
// offer() - returns false if fails (safer)
boolean success = queue.offer("C");
System.out.println("Offer successful? " + success); // true
System.out.println("Queue: " + queue); // [A, B, C]
// ===== RETRIEVING WITHOUT REMOVING =====
// element() - throws NoSuchElementException if empty
String head1 = queue.element();
System.out.println("\nelement(): " + head1); // A
// peek() - returns null if empty (safer)
String head2 = queue.peek();
System.out.println("peek(): " + head2); // A
System.out.println("Queue unchanged: " + queue); // [A, B, C]
// ===== RETRIEVING AND REMOVING =====
// remove() - throws NoSuchElementException if empty
String removed1 = queue.remove();
System.out.println("\nremove(): " + removed1); // A
// poll() - returns null if empty (safer)
String removed2 = queue.poll();
System.out.println("poll(): " + removed2); // B
System.out.println("Queue after removals: " + queue); // [C]
// ===== TESTING WITH EMPTY QUEUE =====
queue.poll(); // Remove last element
System.out.println("\nQueue is now empty");
// Safe methods return null
System.out.println("peek() on empty: " + queue.peek()); // null
System.out.println("poll() on empty: " + queue.poll()); // null
// Unsafe methods throw exceptions
try {
queue.element(); // Throws NoSuchElementException
} catch (Exception e) {
System.out.println("element() threw: " + e.getClass().getSimpleName());
}
try {
queue.remove(); // Throws NoSuchElementException
} catch (Exception e) {
System.out.println("remove() threw: " + e.getClass().getSimpleName());
}
// ===== BEST PRACTICE =====
System.out.println("\n=== Best Practice ===");
System.out.println("Use offer(), poll(), peek() for safer code!");
}
}

🔑 Key Concepts

FIFO Order

First element added is the first one removed

Add [A, B, C] → Remove gets A, then B, then C

offer() vs add()

offer() returns false if fails, add() throws exception

Use offer() for bounded queues, add() for unbounded

poll() vs remove()

poll() returns null if empty, remove() throws exception

Use poll() to safely check empty queue

peek() vs element()

peek() returns null if empty, element() throws exception

peek() lets you look at front without removing

Best Practices

  • Use LinkedList for simple FIFO queues
  • Use ArrayDeque for better performance (faster than LinkedList)
  • Use PriorityQueue when elements need priority-based ordering
  • Prefer offer()/poll()/peek() over add()/remove()/element() for safer code
  • Don't add null to queues (ArrayDeque and PriorityQueue don't allow it)
  • Use Deque interface when you need both queue and stack operations
  • Consider BlockingQueue for producer-consumer patterns in multithreading

💼 Interview Tips

  • Queue is an interface, not a class - use LinkedList or ArrayDeque
  • PriorityQueue uses heap (binary tree) internally - O(log n) for add/remove
  • ArrayDeque is faster than LinkedList (no node overhead)
  • PriorityQueue doesn't allow null, but LinkedList does
  • Deque (Double-Ended Queue) can work as both queue and stack
  • Know the difference between Deque methods: addFirst/addLast, pollFirst/pollLast
  • Understanding when to use which queue type is important
  • Remember that PriorityQueue is NOT thread-safe