001package horstmann.ch08_queue;
002import java.util.AbstractCollection;
003import java.util.ArrayList;
004import java.util.Iterator;
005
006/**
007    A first-in, first-out bounded collection of objects.
008 */
009public class BoundedQueue<E> extends AbstractCollection<E>
010{
011        /**
012       Constructs an empty queue.
013       @param capacity the maximum capacity of the queue
014       <p><b>Precondition:</b> capacity > 0</p>
015         */
016        public BoundedQueue(int capacity)
017        {
018                elements = new ArrayList<E>(capacity);
019                count = 0;
020                head = 0;
021                tail = 0;
022        }
023
024        public Iterator<E> iterator()
025        {
026                return new
027                                Iterator<E>()
028                {
029                        public boolean hasNext()
030                        {
031                                return visited < count;
032                        }
033
034                        public E next()
035                        {
036                                int index = (head + visited) % elements.size();
037                                E r = elements.get(index);
038                                visited++;
039                                return r;
040                        }
041
042                        public void remove()
043                        {
044                                throw new UnsupportedOperationException();
045                        }
046
047                        private int visited = 0;
048                };
049        }
050
051        /**
052       Remove object at head.
053       @return the object that has been removed from the queue
054       <p><b>Precondition:</b> size() > 0</p>
055         */
056        public E remove()
057        {
058                E r = elements.get(head);
059                head = (head + 1) % elements.size();
060                count--;
061                return r;
062        }
063
064        /**
065       Append an object at tail.
066       @param anObject the object to be appended
067       @return true since this operation modifies the queue.
068       (This is a requirement of the collections framework.)
069       <p><b>Precondition:</b> !isFull()</p>
070         */
071        public boolean add(E anObject)
072        {
073                elements.set(tail,anObject);
074                tail = (tail + 1) % elements.size();
075                count++;
076                return true;
077        }
078
079        public int size()
080        {
081                return count;
082        }
083
084        /**
085       Checks whether this queue is full.
086       @return true if the queue is full
087         */
088        public boolean isFull()
089        {
090                return count == elements.size();
091        }
092
093        /**
094       Gets object at head.
095       @return the object that is at the head of the queue
096       <p><b>Precondition:</b> size() > 0</p>
097         */
098        public E peek()
099        {
100                return elements.get(head);
101        }
102
103        private ArrayList<E> elements;
104        private int head;
105        private int tail;
106        private int count;
107}