Java Arena
Step 4 of 6

ArrayDeque from the library

Java has a ready-made class for stacks and queues: ArrayDeque, in java.util. A deque (said "deck", short for double-ended queue) can add and remove at both of its ends, so it can be a stack or a queue. Unlike the classes this module has built so far, an ArrayDeque keeps its values in an array, not in nodes: an array that it replaces with a bigger one when it's full, like an ArrayList. Unlike an ArrayList, it doesn't shift the other values along when you add or remove at the front. Java's documentation says that most of its operations run in amortized constant time: the same few steps whatever the size, apart from the occasional copy into a bigger array.

As a stack

push, pop and peek work at the front of the deque, which is the stack's top. A painter puts coats of paint on a wall; the last coat is the one you see:

import java.util.ArrayDeque;

public class Main {
    public static void main(String[] args) {
        ArrayDeque<String> coats = new ArrayDeque<>();
        coats.push("primer");
        coats.push("white");
        coats.push("sea blue");
        System.out.println(coats);
        System.out.println("Scraped off: " + coats.pop());
        System.out.println("Now showing: " + coats.peek());
        System.out.println(coats + ", " + coats.size() + " coats");
    }
}
Output
[sea blue, white, primer]
Scraped off: sea blue
Now showing: white
[white, primer], 2 coats

Printing a deque, or going through it with a for-each loop, goes from the front to the back. For a stack, that's top first.

Java also has an old class called Stack. Its own documentation recommends using a Deque such as ArrayDeque in preference to it.

As a queue

offer adds at the back, and poll removes from the front and returns what it removed. peek looks at the front. A juice bar makes the drinks in the order they were ordered:

import java.util.ArrayDeque;

public class Main {
    public static void main(String[] args) {
        ArrayDeque<String> orders = new ArrayDeque<>();
        orders.offer("orange");
        orders.offer("mango");
        orders.offer("beet and apple");
        System.out.println("Making " + orders.poll());
        System.out.println("Next up: " + orders.peek());
        System.out.println("Waiting: " + orders);
        orders.poll();
        orders.poll();
        System.out.println(orders.poll());
        System.out.println(orders.isEmpty());
    }
}
Output
Making orange
Next up: mango
Waiting: [mango, beet and apple]
null
true

On an empty deque, poll and peek return null, while pop throws a NoSuchElementException. An ArrayDeque doesn't accept null as a value (adding one throws a NullPointerException), so a null from poll always means that the deque was empty.

Both ends

Each end has its own methods too: addFirst and addLast, offerFirst and offerLast, removeFirst and removeLast, peekFirst and peekLast, pollFirst and pollLast. push is the same as addFirst, pop as removeFirst, offer as offerLast and poll as pollFirst. A deque used as a stack at its back end (addLast and removeLast) keeps its values in the order they were added, which is handy when you print them. clear() empties a deque.

The variable can have the interface's type, as with List and ArrayList: Deque<String> coats = new ArrayDeque<>(); (with import java.util.Deque;). With var (module 57), var coats = new ArrayDeque<String>(); works too.

Your task

Challenge 1 of 3

A web browser keeps the pages you've opened on a stack, so that its back button can return to the page before. The program reads lines until the line end:

  • back closes the page on top and prints back to and the page that is now on top. When fewer than two pages are open, it prints can't go back instead and changes nothing.
  • Any other line is the name of a page to open: it goes on top.

At end, the program prints now at and the page on top, or no page open if there is none. Use an ArrayDeque as the stack, with push, pop and peek. With this input:

Input
home
news
weather
back
sports
back
back
back
end

the program prints:

back to news
back to news
back to home
can't go back
now at home

Challenge 2

A ticket office serves people in the order they joined the line. The program reads lines until end:

  • join and a name: the person joins the back of the line;
  • serve: the person at the front leaves the line, and the program prints serving and their name, or nobody in line when the line is empty.

At end, it prints still waiting: and the line, front first, as an ArrayDeque prints itself. Use an ArrayDeque as a queue, with offer and poll. With this input:

Input
join Ada
join Bo
serve
join Cy
join Dee
serve
end

the program prints:

serving Ada
serving Bo
still waiting: [Cy, Dee]

Challenge 3

A small text editor has undo and redo. The program reads lines until end:

  • undo takes back the last word typed that is still in the text. It prints nothing to undo when the text is empty.
  • redo puts back the word that the last undo took away (after two undos, two redos put both words back, in their order). It prints nothing to redo when there's nothing to put back. Typing a new word forgets everything that could still be redone.
  • Any other line is a word typed: it goes at the end of the text.

At end, the program prints the text, its words separated by single spaces, or (empty) when it has no words. Use two ArrayDeques: one for the words of the text, and one as a stack of the words that undo took away. With this input:

Input
dear
old
friend
undo
undo
redo
pal
redo
end

the program prints:

nothing to redo
dear old pal