Implementation of Circular Queue in Java with Array

A Circular Queue (also called a Ring Buffer) is a queue data structure that treats its underlying array as if it were connected end-to-end in a circle. Unlike a linear queue, once the rear pointer reaches the end of the array, it wraps back to index 0 — allowing reuse of freed slots without shifting elements.

This post implements a true circular queue in Java using an array, with proper wraparound logic for both the front and rear pointers.

How a Circular Queue Works

  • Both front and rear start at -1 (empty state).
  • Enqueue: Advance rear with wraparound: rear = (rear + 1) % size. The queue is full when (rear + 1) % size == front.
  • Dequeue: Advance front with wraparound: front = (front + 1) % size. Reset both to -1 when the last element is removed.
  • Circular property: Elements can be added to index 0 again after front has moved past it.

Java Program: Circular Queue

import java.io.*;

// Circular queue backed by a fixed-size array
class CircularQueue {
    int item[];   // Array holding queue elements
    int front;    // Index of the front element
    int rear;     // Index of the rear element
    int size;     // Maximum capacity

    public CircularQueue(int capacity) {
        item = new int[capacity];
        front = rear = -1;  // -1 indicates empty queue
        size = capacity;
    }

    // Returns true if the queue is full
    public boolean isFull() {
        return (front == 0 && rear == size - 1)
            || (rear == (front - 1) % (size - 1));
    }

    // Returns true if the queue is empty
    public boolean isEmpty() {
        return (front == -1);
    }

    // Adds an element to the rear of the queue
    public void enqueue(int element) {
        if (isFull()) {
            System.out.println("Queue is full");
        } else {
            if (front == -1) {
                // First element: initialise both pointers to 0
                front = 0;
                rear = 0;
            } else if (rear == size - 1 && front != 0) {
                // Rear has reached end of array; wrap around to beginning
                rear = 0;
            } else {
                rear++;
            }
            item[rear] = element;
        }
    }

    // Removes and returns the front element
    public int dequeue() {
        if (isEmpty()) {
            System.out.println("Queue is empty");
            return -1;
        }
        int removedElement = item[front];
        if (front == rear) {
            // Last element removed; reset to empty state
            front = rear = -1;
        } else if (front == size - 1) {
            // Front was at last index; wrap around
            front = 0;
        } else {
            front++;
        }
        return removedElement;
    }

    // Returns the front element without removing it
    public int peek() {
        if (isEmpty()) {
            System.out.println("Queue is empty");
            return -1;
        }
        return item[front];
    }

    // Displays all elements from front to rear
    public void display() {
        if (isEmpty()) {
            System.out.println("Queue is empty");
            return;
        }
        System.out.print("Queue: ");
        if (rear >= front) {
            // Normal case: no wraparound
            for (int i = front; i <= rear; i++) {
                System.out.print(item[i] + " ");
            }
        } else {
            // Wrapped: print from front to end, then 0 to rear
            for (int i = front; i < size; i++) {
                System.out.print(item[i] + " ");
            }
            for (int i = 0; i <= rear; i++) {
                System.out.print(item[i] + " ");
            }
        }
        System.out.println();
    }
}

public class CircularQueueDemo {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("Enter size of queue: ");
        int size = Integer.parseInt(reader.readLine());
        CircularQueue queue = new CircularQueue(size);
        int choice;

        do {
            System.out.println();
            System.out.println("--- Circular Queue Menu ---");
            System.out.println("1. Enqueue (add element)");
            System.out.println("2. Dequeue (remove element)");
            System.out.println("3. Display queue");
            System.out.println("4. Peek (front element)");
            System.out.println("5. Exit");
            System.out.print("Enter choice: ");
            choice = Integer.parseInt(reader.readLine());

            switch (choice) {
                case 1:
                    System.out.print("Enter element to add: ");
                    int element = Integer.parseInt(reader.readLine());
                    queue.enqueue(element);
                    break;
                case 2:
                    int removed = queue.dequeue();
                    if (removed != -1) System.out.println("Removed: " + removed);
                    break;
                case 3:
                    queue.display();
                    break;
                case 4:
                    int front = queue.peek();
                    if (front != -1) System.out.println("Front element: " + front);
                    break;
                case 5:
                    System.out.println("Exiting...");
                    break;
                default:
                    System.out.println("Invalid choice");
            }
        } while (choice != 5);
    }
}

How the Code Works

  1. CircularQueue class — Wraps an integer array with front, rear, and size fields. Both pointers start at -1.
  2. isFull() — Returns true when the slot just after rear (circularly) equals front, meaning no free slots remain.
  3. enqueue() — On the first insert, sets both front and rear to 0. On subsequent inserts, increments rear, wrapping it to 0 when it hits the array end.
  4. dequeue() — Returns and removes the element at front, then advances front with wraparound. When the last element is removed, both pointers reset to -1.
  5. display() — Handles both the normal case (rear ≥ front) and the wrapped case (rear < front) to print all elements in queue order.

Sample Output

Enter size of queue: 5

--- Circular Queue Menu ---
1. Enqueue (add element)
2. Dequeue (remove element)
3. Display queue
4. Peek (front element)
5. Exit
Enter choice: 1
Enter element to add: 10

--- Circular Queue Menu ---
1. Enqueue (add element)
2. Dequeue (remove element)
3. Display queue
4. Peek (front element)
5. Exit
Enter choice: 1
Enter element to add: 20

--- Circular Queue Menu ---
1. Enqueue (add element)
2. Dequeue (remove element)
3. Display queue
4. Peek (front element)
5. Exit
Enter choice: 1
Enter element to add: 30

--- Circular Queue Menu ---
1. Enqueue (add element)
2. Dequeue (remove element)
3. Display queue
4. Peek (front element)
5. Exit
Enter choice: 1
Enter element to add: 40

--- Circular Queue Menu ---
1. Enqueue (add element)
2. Dequeue (remove element)
3. Display queue
4. Peek (front element)
5. Exit
Enter choice: 1
Enter element to add: 50

--- Circular Queue Menu ---
1. Enqueue (add element)
2. Dequeue (remove element)
3. Display queue
4. Peek (front element)
5. Exit
Enter choice: 1
Enter element to add: 60
Queue is full

--- Circular Queue Menu ---
1. Enqueue (add element)
2. Dequeue (remove element)
3. Display queue
4. Peek (front element)
5. Exit
Enter choice: 3
Queue: 10 20 30 40 50 

--- Circular Queue Menu ---
1. Enqueue (add element)
2. Dequeue (remove element)
3. Display queue
4. Peek (front element)
5. Exit
Enter choice: 4
Front element: 10

--- Circular Queue Menu ---
1. Enqueue (add element)
2. Dequeue (remove element)
3. Display queue
4. Peek (front element)
5. Exit
Enter choice: 2
Removed: 10

--- Circular Queue Menu ---
1. Enqueue (add element)
2. Dequeue (remove element)
3. Display queue
4. Peek (front element)
5. Exit
Enter choice: 2
Removed: 20

--- Circular Queue Menu ---
1. Enqueue (add element)
2. Dequeue (remove element)
3. Display queue
4. Peek (front element)
5. Exit
Enter choice: 3
Queue: 30 40 50 

--- Circular Queue Menu ---
1. Enqueue (add element)
2. Dequeue (remove element)
3. Display queue
4. Peek (front element)
5. Exit
Enter choice: 5
Exiting...

Output Explanation

  • With a capacity of 5, the fifth enqueue fills the queue. The sixth attempt correctly prints Queue is full.
  • After dequeuing 10 and 20, the front pointer advances — and the freed slots at indices 0 and 1 become available for future insertions (the circular advantage).
  • The display correctly shows the remaining elements 30 40 50 in FIFO order.

See Also

Conclusion

Circular queues solve the key limitation of a linear array queue — wasted space at the front after dequeue operations. By wrapping the pointers around, the same array can be reused indefinitely. Circular queues are widely used in operating system buffers, I/O stream processing, and producer-consumer problems where a fixed-size buffer is shared between threads.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.