//TestArrayDequeAsStack.java
//Compare this program with TestStack.java.
//Here are the essential methods you want for a stack,
//to provide the required LIFO behavior:
//push()
//pop()
//peek()
//size()
//isEmpty()
//clear()
//So, the question is: Does an ArrayDeque provide them?
//And the answer, of course, is yes ... along with many
//other methods that are not essential for a stack, but
//are inherited from AbstractCollection<E>, Collection<E>,
//and Iterable<E>, and that should not be used if one is
//adhering strictly to the notion of a LIFO stack.

import static java.lang.System.out;
import java.util.ArrayDeque;
import java.util.Arrays;

public class TestArrayDequeAsStack
{
    public static void main(String[] args)
    {
        System.out.println("=====1=========================");
        //Create an ArrayDeque object to be used as a stack, confirm that
        //it's empty, and display its size. Note that, unlike Deque and
        //Queue, Stack is a class and not an interface, so the programmer
        //is responsible for using the ArrayDeque as a stack.
        ArrayDeque<Integer> sInt = new ArrayDeque<>();
        if (sInt.isEmpty())
        {
            out.println("The stack is empty.");
        }
        else
        {
            out.println("The size of the stack is " + sInt.size() + ".");
        }

        System.out.println("=====2=========================");
        //Add some values to the stack, and then display the
        //first value and the size.
        Integer[] a = { 2, 7, 5, 1, 4, 9 };
        for (int i : a)
        {
            sInt.push(i);
        }
        out.println
        (
            "The value at the top of the stack is "
            + sInt.peek() + "."
        );
        if (sInt.isEmpty())
        {
            out.println("The stack is empty.");
        }
        else
        {
            out.println("The size of the stack is " + sInt.size() + ".");
        }

        System.out.println("=====3=========================");
        //Display the stack as a single entity, along with its size.
        out.println(sInt);
        if (sInt.isEmpty())
        {
            out.println("The stack is empty.");
        }
        else
        {
            out.println("The size of the stack is " + sInt.size() + ".");
        }

        System.out.println("=====4=========================");
        //Clear the stack by removing and displaying one value
        //at a time. Then confirm that it's empty.
        //for (int i : sInt) //<--Can use this for-loop here.
        //As in queue but not in priority queue.
        while (!sInt.isEmpty())
        {
            System.out.print(sInt.pop() + " ");
        }
        out.println();
        if (sInt.isEmpty())
        {
            out.println("The stack is empty.");
        }
        else
        {
            out.println("The size of the stack is " + sInt.size() + ".");
        }

        System.out.println("=====5=========================");
        //Re-create the stack as before, but this time by adding
        //all the elements of an array after converting it to a
        //list. Then display the stack and its size.
        sInt.addAll(Arrays.asList(a));
        out.println(sInt);
        out.println(sInt.size());

        System.out.println("=====6=========================");
        //Clear the stack once more and display it a final time.
        sInt.clear();
        out.println(sInt);
    }
}
/*  Output:
    =====1=========================
    The stack is empty.
    =====2=========================
    The value at the top of the stack is 9.
    The size of the stack is 6.
    =====3=========================
    [9, 4, 1, 5, 7, 2]
    The size of the stack is 6.
    =====4=========================
    9 4 1 5 7 2
    The stack is empty.
    =====5=========================
    [2, 7, 5, 1, 4, 9]
    6
    =====6=========================
    []
*/

