Implementing front, dequeue, and enqueue
The front and dequeue operations start with the same contract check as in LinkedStack. After the check, front returns the value in the head node.
@Override
public T front() {
if (isEmpty()) {
throw new NoSuchElementException();
}
return head.value; // the front item is in the head node
}
The dequeue operation is the same move as LinkedStack’s pop:
@Override
public void dequeue() {
if (isEmpty()) {
throw new NoSuchElementException();
}
head = head.next; // unlink the old front; the next node is the new front
if (head == null) {
tail = null; // the queue is now empty; tail must agree
}
}
The if statement at the end handles removing the only node. Without it, the next enqueue would link the new node after the removed node, and head cannot reach it, so we would lose the new item.
The enqueue operation adds the item at the back.
@Override
public void enqueue(T item) {
if (item == null) {
throw new IllegalArgumentException();
}
Node<T> newNode = new Node<>(item);
if (isEmpty()) {
head = newNode; // the queue was empty; the new node is the front
} else {
tail.next = newNode; // link the new node after the old back
}
tail = newNode; // either way, the new node is the new back
}
The last line runs in both cases.
That completes LinkedQueue.