001package components.queue;
002
003import java.util.Iterator;
004import java.util.NoSuchElementException;
005
006/**
007 * {@code Queue} represented as a singly linked list, done "bare-handed", with
008 * implementations of primary methods.
009 *
010 * <p>
011 * Execution-time performance of all methods implemented in this class is O(1).
012 *
013 * @param <T>
014 *            type of {@code Queue} entries
015 * @convention <pre>
016 * $this.length >= 0  and
017 * [$this.preFront is not null]  and
018 * [$this.rear is not null]  and
019 * [$this.preFront points to the first node of a singly linked list
020 *  containing $this.length + 1 nodes]  and
021 * [$this.rear points to the last node in that singly linked list]  and
022 * [$this.rear.next is null]
023 * </pre>
024 * @correspondence <pre>
025 * this = [data in nodes starting at $this.preFront.next and
026 *  running through $this.rear]
027 * </pre>
028 */
029public class Queue2<T> extends QueueSecondary<T> {
030
031    /*
032     * Private members --------------------------------------------------------
033     */
034
035    /**
036     * Node class for singly linked list nodes.
037     */
038    private final class Node {
039
040        /**
041         * Data in node.
042         */
043        private T data;
044
045        /**
046         * Next node in singly linked list, or null.
047         */
048        private Node next;
049
050    }
051
052    /**
053     * "Smart node" before front node of singly linked list.
054     */
055    private Node preFront;
056
057    /**
058     * Rear node of singly linked list.
059     */
060    private Node rear;
061
062    /**
063     * One less than number of nodes in singly linked list, i.e., length =
064     * |this|.
065     */
066    private int length;
067
068    /**
069     * Creator of initial representation.
070     */
071    private void createNewRep() {
072        this.preFront = new Node();
073        this.preFront.next = null;
074        this.rear = this.preFront;
075        this.length = 0;
076    }
077
078    /*
079     * Constructors -----------------------------------------------------------
080     */
081
082    /**
083     * No-argument constructor.
084     */
085    public Queue2() {
086        this.createNewRep();
087    }
088
089    /*
090     * Standard methods -------------------------------------------------------
091     */
092
093    @SuppressWarnings("unchecked")
094    @Override
095    public final Queue<T> newInstance() {
096        try {
097            return this.getClass().getConstructor().newInstance();
098        } catch (ReflectiveOperationException e) {
099            throw new AssertionError(
100                    "Cannot construct object of type " + this.getClass());
101        }
102    }
103
104    @Override
105    public final void clear() {
106        this.createNewRep();
107    }
108
109    @Override
110    public final void transferFrom(Queue<T> source) {
111        assert source != null : "Violation of: source is not null";
112        assert source != this : "Violation of: source is not this";
113        assert source instanceof Queue2<?>
114                : "Violation of: source is of dynamic type Queue2<?>";
115        /*
116         * This cast cannot fail since the assert above would have stopped
117         * execution in that case: source must be of dynamic type Queue2<?>, and
118         * the ? must be T or the call would not have compiled.
119         */
120        Queue2<T> localSource = (Queue2<T>) source;
121        this.preFront = localSource.preFront;
122        this.rear = localSource.rear;
123        this.length = localSource.length;
124        localSource.createNewRep();
125    }
126
127    /*
128     * Kernel methods ---------------------------------------------------------
129     */
130
131    @Override
132    public final void enqueue(T x) {
133        assert x != null : "Violation of: x is not null";
134        Node p = new Node();
135        Node q = this.rear;
136        p.data = x;
137        p.next = null;
138        q.next = p;
139        this.rear = p;
140        this.length++;
141    }
142
143    @Override
144    public final T dequeue() {
145        assert this.length() > 0 : "Violation of: this /= <>";
146        Node p = this.preFront;
147        Node q = p.next;
148        T result = q.data;
149        this.preFront = q;
150        this.length--;
151        return result;
152    }
153
154    @Override
155    public final int length() {
156        return this.length;
157    }
158
159    @Override
160    public final Iterator<T> iterator() {
161        return new Queue2Iterator();
162    }
163
164    /**
165     * Implementation of {@code Iterator} interface for {@code Queue2}.
166     */
167    private final class Queue2Iterator implements Iterator<T> {
168
169        /**
170         * Current node in the linked list.
171         */
172        private Node current;
173
174        /**
175         * No-argument constructor.
176         */
177        private Queue2Iterator() {
178            this.current = Queue2.this.preFront.next;
179        }
180
181        @Override
182        public boolean hasNext() {
183            return this.current != null;
184        }
185
186        @Override
187        public T next() {
188            assert this.hasNext() : "Violation of: ~this.unseen /= <>";
189            if (!this.hasNext()) {
190                /*
191                 * Exception is supposed to be thrown in this case, but with
192                 * assertion-checking enabled it cannot happen because of assert
193                 * above.
194                 */
195                throw new NoSuchElementException();
196            }
197            T x = this.current.data;
198            this.current = this.current.next;
199            return x;
200        }
201
202        @Override
203        public void remove() {
204            throw new UnsupportedOperationException("remove operation not supported");
205        }
206
207    }
208
209    /*
210     * Other methods (overridden for performance reasons) ---------------------
211     */
212
213    @Override
214    public final T replaceFront(T x) {
215        assert x != null : "Violation of: x is not null";
216        assert this.length() > 0 : "Violation of: this /= <>";
217        T front = this.preFront.next.data;
218        this.preFront.next.data = x;
219        return front;
220    }
221
222}