Java implementation for stack

Viewed 210

Is there a class in Java that implements the concept of Stack form the data structure books, means LIFO, pop is O(1) and push in O(1)?

I read a bit the code of java.util.Stack and it is doesn't seems that push is O(1) - push can call Vector.grow() and it can take O(n) ( I know it amortized O(1) but I looking for always push in O(1) )

And I want to understand why java.util.Stack was designed as is, not as the theoretical principle of stack

5 Answers

ArrayDeque is preferable to LinkedList.

Because it is backed by an array, rather than storing the individual elements in separate node instances, it is far more performant.

According to Josh Bloch, author of LinkedList, in tweets:

Does anyone actually use LinkedList? I wrote it, and I never use it.

and

ArrayDeque makes a great stack, queue, or deque

You could use LinkedList or ArrayDeque which implement Deque interface and this interface has stack-like methods pop and push. Because LinkedList and ArrayDeque implement this interface, we can use them as if we were using a Stack.

From the docs of Deque :

Deques can also be used as LIFO (Last-In-First-Out) stacks. This interface should be used in preference to the legacy Stack class. When a deque is used as a stack, elements are pushed and popped from the beginning of the deque.

So as you can see implementations of Deque should be preferred over legacy Stack class.

tl;dr

Stack is now legacy code

The java.util.Stack class is now legacy, extending from another legacy class, java.util.Vector. You should not be using these classes. Nor should you be studying them as shining examples.

Java Collections Framework

Both of these classes were supplanted two decades ago, by the Java Collections Framework.

For LIFO behavior, you should be looking at the classes that implement the queue interfaces and deque interfaces.

The java.util.Queue interface is implemented in many classes bundled with Java.

  • AbstractQueue
  • ArrayBlockingQueue
  • ArrayDeque
  • ConcurrentLinkedDeque
  • ConcurrentLinkedQueue
  • DelayQueue
  • LinkedBlockingDeque
  • LinkedBlockingQueue
  • LinkedList
  • LinkedTransferQueue
  • PriorityBlockingQueue
  • PriorityQueue
  • SynchronousQueue

You may find LIFO collections implemented elsewhere in 3rd party libraries, perhaps Google Guava.

LinkedList

As others mentioned, the first to consider is LinkedList for O(1) behavior as discussed on How is LinkedList's add(int, E) of O(1) complexity?.

Stack or Queue both can be implemented with Linkedlist.

pop ( ) : Remove the top item from the stack.

push (): Add an item to the top of the stack.

public class MyStack<T> {

   private StackNode<T> top;
    private static class StackNode<T> {

        private T data;
        private StackNode<T> next;

        public StackNode(T data) {
            this.data = data;
        }
    }

    public T pop() {
        if (top == null) throw new EmptystackException();
        T item = top.data;
        top = top.next;
        return item;
    }

    public void push(T item) {

        StackNode<T> t = new StackNode<T>(item);
        t.next = top;
        top = t;
    }
}

The stack is a linear data structure. It works under LIFO(Last In First Out mechanism) and it has 3 basic operations: Pop(), Push(), and peek(). Push and Pop operations can be performed only at one end that is called top. peek() operation is to display elements in a stack.

Below is the JAVA implementation of STACK. The datatype we will store in Stack is String

When Stack is full, it is called 'OVERFLOW', and when the stack is empty, we call this 'UNDERFLOW'

public class StackOfString {

int top = -1;
String[] myStack;

public StackOfString() {
    this.myStack = new String[5];
}

public void pop() {
    if (top != -1) {
        System.out.println("Item to be Poped: " + myStack[top]);
        myStack[top] = null;
        top -= 1;
    } else {
        System.out.println("Stack is UNDERFLOW!!!");
    }
}

public void push(String str) {
    if (isFull()) {
        top += 1;
        myStack[top] = str;
    }else {
        System.out.println("Stack is OVERFLOW!!!");
    }
    

}

public boolean isFull() {
    if (top < (myStack.length -1)) {
        return true;
    } else {
        return false;
    }
}

public void peek() {
    for (String string : myStack) {
        if (string != null)
            System.out.println(string);
    }
}}

public class Client {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    StackOfString stackOfString = new StackOfString();

    stackOfString.pop();

    stackOfString.push("A");
    stackOfString.push("B");
    stackOfString.push("C");
    stackOfString.push("D");
    stackOfString.push("E");
    stackOfString.peek();
    stackOfString.push("F");

    stackOfString.pop();
    stackOfString.pop();
    stackOfString.pop();
    stackOfString.pop();
    stackOfString.pop();
    stackOfString.pop();
}}

This is the output:

Click here to see Output

Related