Repository: TheAlgorithms/Java
File: src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java (Java)

Code before:

    /**
     * Retrieves and removes the item at the front of the buffer (FIFO).
     *
     * @return The item at the front of the buffer, or {@code null} if the buffer is empty.
     */
    public Item get() {
        if (isEmpty()) {
            return null;
        }

        Item item = buffer[getPointer.getAndIncrement()];
        size.decrementAndGet();
        return item;
    }

    /**
     * Adds an item to the end of the buffer (FIFO).
     *
     * @param item The item to be added.
     * @return {@code true} if the item was successfully added, or {@code false} if the buffer is full.
     */
    public boolean put(Item item) {
        if (isFull()) {
            return false;
        }

        buffer[putPointer.getAndIncrement()] = item;
        size.incrementAndGet();
        return true;
    }

    /**
     * The {@code CircularPointer} class is a helper class used to track the current index (pointer)
     * in the circular buffer. It automatically wraps around when reaching the maximum index.
     */
    private static class CircularPointer {
        private int pointer;
        private final int max;

        /**
         * Constructor to initialize the circular pointer.
         *
         * @param pointer The initial position of the pointer.
         * @param max The maximum size (capacity) of the circular buffer.
         */
        CircularPointer(int pointer, int max) {
            this.pointer = pointer;
            this.max = max;
        }


Review comment (bug):
- What happens when the item is null? If null items are not allowed, you could throw an exception like IllegalArgumentException and document that.

- Clarify that it overwrites old data if the buffer is full, if that's the intended behavior, or mention that it fails silently.

Code after:
     * The buffer is considered full when its size equals its capacity.
     *
     * @return {@code true} if the buffer is full, {@code false} otherwise.
     */
    public boolean isFull() {
        return size.get() == buffer.length;
    }

    /**
     * Retrieves and removes the item at the front of the buffer (FIFO).
     * This operation will move the {@code getPointer} forward.
     *
     * @return The item at the front of the buffer, or {@code null} if the buffer is empty.
     */
    public Item get() {
        if (isEmpty()) {
            return null;
        }

        Item item = buffer[getPointer.getAndIncrement()];
        size.decrementAndGet();
        return item;
    }

    /**
     * Adds an item to the end of the buffer (FIFO).
     * If the buffer is full, this operation will overwrite the oldest data.
     *
     * @param item The item to be added.
     * @throws IllegalArgumentException if the item is null.
     * @return {@code true} if the item was successfully added, {@code false} if the buffer was full and the item overwrote existing data.
     */
    public boolean put(Item item) {
        if (item == null) {
            throw new IllegalArgumentException("Null items are not allowed");
        }

        boolean wasEmpty = isEmpty();
        if (isFull()) {
            getPointer.getAndIncrement(); // Move get pointer to discard oldest item
        } else {
            size.incrementAndGet();
        }

        buffer[putPointer.getAndIncrement()] = item;
        return wasEmpty;
    }

    /**
     * The {@code CircularPointer} class is a helper class used to track the current index (pointer)
     * in the circular buffer.