public final class DoublyLinkedList { private Element head; public void push(T value) { if (head == null) { head = new Element<>(value, null, null); head.next = head; head.prev = head; return; } Element oldTail = head.prev; Element tail = new Element<>(value, oldTail, head); oldTail.next = tail; head.prev = tail; } public T pop() { head = head.prev; return shift(); } public void unshift(T value) { push(value); head = head.prev; } public T shift() { T value = head.value; Element newHead = head.next; Element newTail = head.prev; if (newHead == head) { head = null; } else { newHead.prev = newTail; newTail.next = newHead; head = newHead; } return value; } private static final class Element { private final T value; private Element prev; private Element next; public Element(T value, Element prev, Element next) { this.value = value; this.prev = prev; this.next = next; } } }