Queues Explained

    Atul Kabra4 min readUpdated

    A queue is a collection that follows FIFO order — first in, first out. You add items at one end (the rear) and remove them from the other (the front), just like a line of people at a ticket counter: whoever arrives first is served first. Done correctly, both adding and removing run in O(1) time.

    The core operations

    A queue exposes a tight set of operations:

    • enqueue — add an item at the rear.
    • dequeue — remove and return the item at the front.
    • front (or peek) — look at the front item without removing it.
    • isEmpty — check whether the queue is empty.

    Because you can only touch the two ends, the queue enforces fairness: items leave in the exact order they arrived.

    Why FIFO matters

    Queues model anything that should be processed in order of arrival. A printer holds print jobs in a queue. An operating system schedules tasks. A web server buffers incoming requests. Message systems pass events through queues so nothing is processed out of turn. The discipline of "first come, first served" is the whole value.

    Implementing a queue in Java

    A naive array queue that shifts elements on every dequeue would be O(n). Instead we use two indices, front and rear, that move forward, keeping every operation O(1). (A production version wraps these indices around — see circular queues — but the linked approach below is simplest to reason about.)

    // A queue backed by a singly linked list.
    // enqueue and dequeue are both O(1) thanks to head and tail pointers.
    class IntQueue {
        private static class Node {
            int data;
            Node next;
            Node(int v) { data = v; }
        }
    
        private Node front; // remove from here
        private Node rear;  // add here
    
        // Add a value at the rear of the queue.
        public void enqueue(int value) {
            Node node = new Node(value);
            if (rear == null) {        // queue was empty
                front = rear = node;
            } else {
                rear.next = node;      // link old rear to new node
                rear = node;           // new node becomes the rear
            }
        }
    
        // Remove and return the value at the front.
        public int dequeue() {
            if (front == null) {
                throw new RuntimeException("Queue is empty");
            }
            int value = front.data;
            front = front.next;        // advance the front
            if (front == null) {       // queue is now empty
                rear = null;
            }
            return value;
        }
    
        public boolean isEmpty() {
            return front == null;
        }
    
        public static void main(String[] args) {
            IntQueue q = new IntQueue();
            q.enqueue(10);
            q.enqueue(20);
            q.enqueue(30);
            System.out.println(q.dequeue()); // 10 (first in, first out)
            System.out.println(q.dequeue()); // 20
        }
    }
    

    Each operation updates only the front or rear pointer, so the cost never depends on the number of items.

    Want to learn this properly?

    Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.

    Browse courses

    Queue versus stack

    AspectStackQueue
    OrderLIFO (last in, first out)FIFO (first in, first out)
    Add atTopRear
    Remove fromTopFront
    Typical useUndo, recursion, backtrackingScheduling, buffering, BFS

    The two are mirror images. Choosing the right one is often the first decision in solving a problem. For example, breadth-first traversal of a graph uses a queue, while depth-first uses a stack.

    Variations

    • Circular queue — reuses array slots so the front can wrap around, avoiding wasted space. See Circular Queues Explained.
    • Deque — a double-ended queue that lets you add and remove from both ends.
    • Priority queue — items leave in priority order rather than arrival order, usually backed by a heap.

    Common mistakes

    • Dequeuing an empty queue. Removing from an empty queue is a common bug. Check isEmpty or handle the error.
    • Using a shifting array. A plain array that shifts every element on dequeue makes the operation O(n). Use two moving indices or a linked list to keep it O(1).
    • Forgetting to reset rear. When the last element is dequeued, both front and rear must become null. Updating only front leaves a dangling rear pointer.
    • Confusing it with a stack. If your problem needs the most recent item first, you want a stack, not a queue.

    FAQ

    When do I use a queue over a stack? Use a queue when order of arrival must be preserved — scheduling, buffering, level-order traversal. Use a stack when you need the most recent item first.

    What is a circular queue? It is a fixed-size queue that reuses freed slots by wrapping indices around, so you do not waste the front of the array. Read Circular Queues Explained.

    Keep learning

    Compare with Stacks Explained, move on to the space-efficient Circular Queue, and browse the full DSA hub.

    Want to practise queue-based problems with instructor feedback in Jalgaon? Join the waitlist for our Data Structures & Algorithms course.

    Want to learn this properly?

    Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.

    Browse courses
    Atul Kabra

    Founder, Infoplanet

    Atul Kabra founded Infoplanet in 2001 and has spent over two decades teaching programming — C, C++, Java, databases and more — to students across Maharashtra.

    Related guides