Most of circular Queue implementations I have found keep track of the head and tail of queue. Adding and removing items are done using head and tail pointers.
I decided to implement a circular queue my using modulo operation to figure head and tail instead of defining head and tail pointer variables.
The queue class also implements Iterable so that the usual ‘for’ comprehension can be used to iterate through the queue.

The queue is backed by ArrayList and as such its not thread-safe.

Although in reality queue class should only expose enqueue(),dequeue(),size() and isEmpty() methods to keep the API clean , I implementation has extra methods to provide
list operations.
Although allowing index based access may not really be that useful since item indexes will be rotated when items overwrite existing items, I couldn’t help but over-engineer the queue :-)

here’s the iterable circular queue implementation:


public class IterableCircularQueue<T> implements Iterable<T> {

    private final int capacity;
    private List<T> list;
    private int count = 0;

    public IterableCircularQueue(int capacity) {
        this.capacity = capacity;
        list = new ArrayList<T>(capacity);

    }

    /**
     * add item to queue
     * @param elem
     */
    public void enqueue(T elem) {

        if (count < capacity) {
            list.add(elem);
        } else {
            if (list.size() == capacity) {
                list.set(count % capacity, elem);
            } else {
                list.add(count % capacity, elem);
            }
        }
        count++;

    }

    /**
     * Inspect the first item of the queue.
     * @return
     */
    public T peek() {

        if (list.isEmpty()) {
            throw new RuntimeException(" queue is empty");
        }
        T value = null;
        if (count > capacity) {
            int head = count % capacity;
            if (head >= list.size()) {
                head = head - list.size();
            }
            value = list.get(head);
        } else {
            value = list.get(0);
        }

        return value;
    }

    /**
     * remove an item from the queue
     * @return
     */
    public T dequeue() {

        if (list.isEmpty()) {
           throw new RuntimeException(" queue is empty");
        }
        T value = null;
        if (count > capacity) {
            int head = count % capacity;
            if (head >= list.size()) {
                head = head - list.size();
            }
            value = list.remove(head);
        } else {
            value = list.remove(0);
        }
        if (list.isEmpty()) {
            count = 0;
        }

        return value;
    }

    /**
     * index-based access to items in queue.
     * @note The item won't be removed when accessed using index
     * @param index
     * @return
     */
    public T get(int index) {

        if (index < 0 || index >= list.size()) {
            throw new IndexOutOfBoundsException();
        }

        int i = index;

        if (count > capacity) {
            i = count % capacity + index;
            if (i >= list.size()) {
                i = i - list.size();
            }
        }
        return list.get(i);
    }

    /**
     * number of items in queue
     * @return
     */
    public int size() {
        return list.size();
    }

    /**
     * check if the queue is empty
     * @return
     */
    public boolean isEmpty() {
        return list.isEmpty();
    }

    public String toString() {
        return list.toString();
    }

    /**
     * Fetch an Iterator to iterate through the queue.
     * @return
     */
    public Iterator<T> iterator() {
        return new QueueIterator();
    }

    /**
     * Queue Iterator implementation
     */
    private class QueueIterator implements Iterator<T> {

        int cursor = 0;

        public boolean hasNext() {

            if (cursor >= capacity) {
                return false;
            }

            try {
                return get(cursor) != null;
            } catch (Exception e) {
                return false;
            }
        }

        public T next() {
            T val = get(cursor);
            cursor++;
            return val;
        }

        public void remove() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
}

Test cases:


 IterableCircularQueue<Integer> q = new IterableCircularQueue(5);

        q.enqueue(0);
        q.enqueue(1);
        q.enqueue(2);
        q.enqueue(3);
        q.enqueue(4);

        assertEquals(new Integer(4), q.get(4));

        q.enqueue(5);// first item gets over-written

        assertEquals(new Integer(5), q.get(4));
         assertEquals(new Integer(1), q.dequeue());

        q.enqueue(6);
        q.enqueue(7);

        assertEquals(new Integer(3), q.dequeue());

        assertEquals(new Integer(5), q.get(1));
        assertEquals(new Integer(6), q.get(2));

        q.enqueue(8);
        q.enqueue(9);

        assertEquals(new Integer(6), q.get(1));
        assertEquals(new Integer(5), q.dequeue());
        assertEquals(new Integer(7), q.get(1));
        assertEquals(new Integer(6), q.dequeue());
        assertEquals(new Integer(8), q.get(1));

         assertEquals(new Integer(7), q.peek());

        assertEquals(new Integer(7), q.dequeue());
        assertEquals(new Integer(8), q.dequeue());
        assertEquals(new Integer(9), q.dequeue());

        assertTrue( q.isEmpty());

        q.enqueue(10);
        q.enqueue(11);
        q.enqueue(12);
        q.enqueue(13);

        assertEquals(new Integer(10), q.get(0));

        q.enqueue(14);
        q.enqueue(15);
        q.enqueue(16);
        q.enqueue(17);

        assertEquals(new Integer(13), q.get(0));
        assertEquals(new Integer(13), q.peek());
        assertEquals(new Integer(13), q.dequeue());
        assertEquals(new Integer(14), q.get(0));

        System.out.println(q);//prints [15,16,17,14]

        for (Integer i : q) {
            System.out.println(i + " "); //prints 14 15 16 17
        }