TheAlgorithms/Java · error · IllegalStateException

Queue is empty

Error message

Queue is empty

What it means

Thrown by CircularQueue.deQueue() as an IllegalStateException when isEmpty() is true (currentSize == 0). The queue refuses to return a front element it does not have. This is the standard underflow guard for a bounded ring buffer.

Source

Thrown at src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java:94

            throw new IllegalStateException("Queue is full");
        }
        if (isEmpty()) {
            beginningOfQueue = 0;
        }
        topOfQueue = (topOfQueue + 1) % size;
        array[topOfQueue] = value;
        currentSize++;
    }

    /**
     * Removes and returns the element at the front of the queue.
     *
     * @return the element at the front of the queue
     * @throws IllegalStateException if the queue is empty
     */
    public T deQueue() {
        if (isEmpty()) {
            throw new IllegalStateException("Queue is empty");
        }
        T removedValue = array[beginningOfQueue];
        array[beginningOfQueue] = null; // Optional: Nullify to help garbage collection
        beginningOfQueue = (beginningOfQueue + 1) % size;
        currentSize--;
        if (isEmpty()) {
            beginningOfQueue = -1;
            topOfQueue = -1;
        }
        return removedValue;
    }

    /**
     * Returns the element at the front of the queue without removing it.
     *
     * @return the element at the front of the queue
     * @throws IllegalStateException if the queue is empty
     */

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Call isEmpty() (or isFull() check) before deQueue() and skip or wait when the queue is empty.
  2. Track enqueued vs dequeued counts in the caller to prevent over-dequeue in loops.
  3. Wrap the call in try/catch(IllegalStateException) if the empty case should be handled as a normal control-flow signal.
  4. For concurrent use, replace with a blocking queue so the consumer waits instead of throwing.

Example fix

// before
T v = queue.deQueue(); // throws when empty

// after
T v = null;
if (!queue.isEmpty()) {
    v = queue.deQueue();
}
Defensive patterns

Strategy: validation

Validate before calling

if (!queue.isEmpty()) {
    T v = queue.deQueue();
}

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Calling deQueue() on a freshly constructed CircularQueue, or calling deQueue() more times than enQueue() has been called. Also triggered after deleteQueue() resets state if the instance is still referenced.

Common situations: Consumer draining a queue the producer has not yet filled; off-by-one loop where the dequeue count exceeds the enqueue count; draining logic running once more after the queue is exhausted; shared queue where one consumer races ahead of production.

Related errors


AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13). Data as JSON: /api/errors/b9a9937928d3b121. Report an issue: GitHub.