Create a Stack generic class that represents a stack (placing an item on top of the stack, removing an item from the top of the stack, querying the topmost item, querying the size, throwing exceptions in case of errors)!
How can I fix this? I do not have any idea.
import java.util.*;
public class Stack<T> {
private T[] stack = null;
private int size = 0;
public void push(T x) {
stack[size] = x;
size ;
}
public T pop() throws Exception{
if (size == 0) {
throw new NoSuchElementException("Cannot pop from empty stack");
}else{
size--;
return stack[size];
}
}
public T top() throws Exception {
if (size == 0) {
throw new NoSuchElementException("The stack is empty");
}else{
return stack[size-1];
}
}
public int size() {
return size;
}
public static void main(String[] args) throws Exception{
Stack<Integer> stack1 = new Stack<Integer>();
stack1.push(213);
stack1.push(345);
stack1.push(987);
while(stack1.size() > 0){
System.out.println(stack1.pop());
}
System.out.println("\n");
Stack<String> stack2 = new Stack<String>();
stack2.push("1");
stack2.push("2");
stack2.push("3");
stack2.push("4");
while(stack2.size() > 0){
System.out.println(stack2.pop());
}
}
}
I got an error message :
Exception in thread "main" java.lang.NullPointerException
at Stack.push(Stack.java:12)
at Stack.main(Stack.java:41)
CodePudding user response:
With the line private T[] stack = null;
You don't initialize an array. Therefore you get NullPointerException when calling pop()
, top()
, push(t)
on it.
What you miss is a constructor for your stack, where you pass the max capacity for the stack and after that you have to initialize an array with that size.
import java.util.NoSuchElementException;
@SuppressWarnings("unchecked")
public class Stack<T> {
private final int capacity; // remember capacity
private final Object[] stack; // array of type Object
private int size = 0;
public Stack(int capacity) {
this.capacity = capacity;
this.stack = new Object[capacity]; // initialize new array
}
public void push(T x) {
if (size == capacity) { // check for sufficient capacity
throw new IllegalStateException("Stack is full.");
}
stack[size] = x;
size ;
}
public T pop() {
if (size == 0) {
throw new NoSuchElementException("Cannot pop from empty stack");
}else{
size--;
return (T) stack[size]; // cast result
}
}
public T top() {
if (size == 0) {
throw new NoSuchElementException("The stack is empty");
}else{
return (T) stack[size-1]; // cast result
}
}
public int size() {
return size;
}
}
Note, that capacity is the max size of data your stack can maintain and size would be the currentl capacity in use. You would also check for sufficient capacity before pushing something onto it. As @rzwitserloot mentioned is the creation of an generic array not trivial, the easiest would be to create an Object array and casting the retrieval of their entries.
Otherwise (which is much more complicated) you have to dynamically resize the backend array when adding something to it, while it is full or switch the array for an ArrayList.