Queue
The interface Queue
- boolean add(E e) inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions, returning true upon success and throwing an IllegalStateException if no space is currently available.
- boolean offer(E e) inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions.
- E remove() retrieves and removes the head of this queue; if it's empty, the method throws NoSuchElementException.
- E poll() retrieves and removes the head of this queue, or returns null if this queue is empty.
- E element() retrieves, but does not remove, the head of the queue; if it's empty, the method throws NoSuchElementException.
- E peek() retrieves, but does not remove, the head of this queue, or returns null if this queue is empty.
Stack
A helpful analogy is to think of a stack of books; you can remove only the top book, also you can add a new book on the top.
The Standard Class Library has the class Stack, but, according to JavaDoc, a more complete and consistent set of LIFO stack operations is provided by the Deque interface and its implementations, which should be used in preference to this class.
Deque
The java.util.Deque<E> interface extends the interface. java.util.Queue<E>. It represents a queue where you can insert and remove elements from both ends of the queue. Thus, "Deque" is short for "Double-Ended Queue".
It has methods for working with the first and the last element of a queue:
There are two implementations of the interface Deque: ArrayDeque and LinkedList. So, these classes can work as Queue (FIFO), Stack (LIFO), and Deque (Double-Ended Queue).
Deque in practice
It's possible to use implementations of the Deque interface as a queue (FIFO).
Queue<String> q = new ArrayDeque<>();
q.add("first");
q.add("second");
q.add("third");
System.out.println(q.peek()); // "first", it doesn't remove the element
System.out.println(q.peek()); // "first"
System.out.println(q.remove()); // "first", it removes and returns the head element
System.out.println(q.peek()); // "second"
System.out.println(q.remove()); // "second"
System.out.println(q.remove()); // "third"
System.out.println(q.isEmpty()); // "true"
Also, it's possible to use any implementation of the Deque interface as a stack (LIFO).
Deque<String> stack = new ArrayDeque<>();
stack.offerLast("first");
stack.offerLast("second");
stack.offerLast("third");
System.out.println(stack); // [first, second, third]
System.out.println(stack.pollLast()); // "third"
System.out.println(stack.pollLast()); // "second"
System.out.println(stack.pollLast()); // "first"
System.out.println(stack.pollLast()); // null
The old Stack class
But sometimes, the class Stack<E> with more a minimalistic API is used. It doesn't implement Deque or Queue interface.
See an example below.
Stack<String> stack = new Stack<>();
stack.push("first");
stack.push("second");
stack.push("third");
System.out.println(stack); // [first, second, third]
System.out.println(stack.pop()); // "third"
System.out.println(stack.pop()); // "second"
System.out.println(stack.pop()); // "first"
System.out.println(stack.pop()); // throws EmptyStackException