//TestStack.java
//Compare this program with TestArrayDequeAsStack.java.
//Here are the minimal essential methods you need for a
//stack to provide the required LIFO behavior:
//push()
//pop()
//peek()
//empty() Note: Not isEmpty() like in ArrayDeque.

//search()
//Note that the search() method is available in the Java Stack interface,
//but a method like this should not be part of *any* Stack interface
//because it violates the essential LIFO behavior that characterizes
//the stack container type.
//Note: The following three methods are not in the Stack interface itself
//but are available from Vector, from which Stack is inherited.
//size()
//clear()
//addAll()
//remove()
import static java.lang.System.out;
import java.util.Arrays;
import java.util.Stack;

public class TestStack
{
    public static void main(String[] args)
    {
        System.out.println("=====1=========================");
        //Create a stack, confirm that it's empty, and display its size.
        Stack<Integer> sInt = new Stack<>();
        if (sInt.empty())
        {
            out.println("The stack is empty.");
        }
        out.println("The size of the stack is " + sInt.size() + ".");

        System.out.println("=====2=========================");
        //Add some values to the stack, and then display the
        //top value and the size (and also do some searching,
        //which should not be possible for a stack!).
        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() + "."
        );
        out.println("The size of the stack is " + sInt.size() + ".");

        int locationIndex = sInt.search(3);
        if (locationIndex == -1)
            out.println("The value 3 is not in the stack.");
        else
            out.println
            (
                "The value 3 is at position "
                + sInt.search(3) + " in the stack."
            );

        locationIndex = sInt.search(7);
        if (locationIndex == -1)
            out.println("The value 7 is not in the stack.");
        else
            out.println
            (
                "The value 7 is at position "
                + sInt.search(7) + " in the stack."
            );

        System.out.println("=====3=========================");
        //Display the stack as a single entity, along with its size.
        out.println(sInt);
        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.
        while (!sInt.empty()) //<--Cannot use for (int i : sInt) here!
            System.out.print(sInt.pop() + " ");
        out.println();
        out.println
        (
            "The stack is " + (sInt.empty() ? "" : " not ")
            + "empty."
        );
        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);

        //The following code segments illustrate some additional things
        //you should not be able to do with a stack, since they violate
        //the notion of "stackness". The fact that you can do them is a
        //reflection of the fact that, in Java, the Stack class inherits
        //from the Vector class, in which you *can* do these things.
        System.out.println("=====7=========================");
        out.println(sInt.capacity());
        sInt.addAll(Arrays.asList(a));
        out.println(sInt.size());
        out.println(sInt);
        System.out.println("=====8=========================");
        sInt.sort((m, n) -> m - n);
        out.println(sInt);

        System.out.println("=====9=========================");
        out.println(sInt.remove(2) + " removed from stack.");
        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.
    The value 3 is not in the stack.
    The value 7 is at position 5 in the stack.
    =====3=========================
    [2, 7, 5, 1, 4, 9]
    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=========================
    []
    =====7=========================
    10
    6
    [2, 7, 5, 1, 4, 9]
    =====8=========================
    [1, 2, 4, 5, 7, 9]
    =====9=========================
    4 removed from stack.
    [1, 2, 5, 7, 9]
*/

