Jump to content

Java Stack.push() returns NullPointerException

Claryn
Go to solution Solved by Pinguinsan,

Any time you use a reference type in Java for a class member , it will be null until it has been assigned using the new keyword. You must first initialize it, preferably in the constructor for your class.

import java.util.EmptyStackException;
import java.lang.Math;
import java.util.Stack;

public class RPNCalc {
	
	Stack<Double> st;
	double first; 
	double second;
	
	//Constructor for RPNCalc, called anytime a new RPNCalc is created with the new keyword, as you do in
	//the first line of Main
	public RPNCalc() {
		this.st = new Stack<Double>(); //Initialize member variable st to a new Stack<Double>() so it can be used
	}

	public static void main(String[] args) {
		RPNCalc test = new RPNCalc(); //Calls RPNCalc constructor
		test.push(1.0);
		System.out.println(test.getSize());
		System.out.println(test.pop());
	}
      
      	
	// place the number/argument on the top of the stack
	void push(double number) {
		st.push(number);
	}
      
 	// get size of stack
	int getSize() {
		
		Stack<Double> tmpStack = new Stack(); // create new temorary stack
		tmpStack = this.st; // set tmpStack to st
		
		int counter = 0;
		
		// iterate through the tmpStack until it is empty, and count elements
		while (true) {
			
			try {				
				tmpStack.pop(); 
			} catch (EmptyStackException e) {
				break; // break if stack is empty
			} catch (NullPointerException e) {
				break; // break if the stack is empty
			}
			counter++; // count the elements in the stack
		}
		
		return counter;
	}
  }

 

Hi.

Im working on an RPNCalculator, using a Stack to hold the operands.

 

Currently my code looks like this:

import java.util.EmptyStackException;
import java.lang.Math;
import java.util.Stack;

public class RPNCalc {
	
	Stack<Double> st;
	double first; 
	double second;
	
	public static void main(String[] args) {
		RPNCalc test = new RPNCalc();
		test.push(1.0);
		System.out.println(test.getSize());
		System.out.println(test.pop());
	}
      
      	
	// place the number/argument on the top of the stack
	void push(double number) {
		st.push(number);
	}
      
 	// get size of stack
	int getSize() {
		
		Stack<Double> tmpStack = new Stack(); // create new temorary stack
		tmpStack = this.st; // set tmpStack to st
		
		int counter = 0;
		
		// iterate through the tmpStack until it is empty, and count elements
		while (true) {
			
			try {				
				tmpStack.pop(); 
			} catch (EmptyStackException e) {
				break; // break if stack is empty
			} catch (NullPointerException e) {
				break; // break if the stack is empty
			}
			counter++; // count the elements in the stack
		}
		
		return counter;
	}
  }

 

Currently, my test.push(1.0); causes a NullPointerException at st.push(number); in the push method. Why is that? I know that the Stack is empty, but from all online resources I have checked, this is the way to add an element to the Stack.

 

Running Arch with i3-gaps on a Thinkpad X1 Extreme
Data Science Postgrad

 

Link to comment
Share on other sites

Link to post
Share on other sites

Any time you use a reference type in Java for a class member , it will be null until it has been assigned using the new keyword. You must first initialize it, preferably in the constructor for your class.

import java.util.EmptyStackException;
import java.lang.Math;
import java.util.Stack;

public class RPNCalc {
	
	Stack<Double> st;
	double first; 
	double second;
	
	//Constructor for RPNCalc, called anytime a new RPNCalc is created with the new keyword, as you do in
	//the first line of Main
	public RPNCalc() {
		this.st = new Stack<Double>(); //Initialize member variable st to a new Stack<Double>() so it can be used
	}

	public static void main(String[] args) {
		RPNCalc test = new RPNCalc(); //Calls RPNCalc constructor
		test.push(1.0);
		System.out.println(test.getSize());
		System.out.println(test.pop());
	}
      
      	
	// place the number/argument on the top of the stack
	void push(double number) {
		st.push(number);
	}
      
 	// get size of stack
	int getSize() {
		
		Stack<Double> tmpStack = new Stack(); // create new temorary stack
		tmpStack = this.st; // set tmpStack to st
		
		int counter = 0;
		
		// iterate through the tmpStack until it is empty, and count elements
		while (true) {
			
			try {				
				tmpStack.pop(); 
			} catch (EmptyStackException e) {
				break; // break if stack is empty
			} catch (NullPointerException e) {
				break; // break if the stack is empty
			}
			counter++; // count the elements in the stack
		}
		
		return counter;
	}
  }

 

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Claryn said:

Hi.

Im working on an RPNCalculator, using a Stack to hold the operands.

 

Currently my code looks like this...

 

I'm not a java programmer but this looks fishy:

Stack<Double> tmpStack = new Stack(); // create new temorary stack
tmpStack = this.st; // set tmpStack to st

Surely it must be this.st = tmpStack ?

As it is now you lose the tmpStack you just created by overwriting it.

Link to comment
Share on other sites

Link to post
Share on other sites

5 hours ago, Pinguinsan said:

 


		while (true) {
			
			try {				
				tmpStack.pop(); 
			} catch (EmptyStackException e) {
				break; // break if stack is empty
			} catch (NullPointerException e) {
				break; // break if the stack is empty
			}
		}

 

 

Do not use exceptions to manage program control flow. The stack interface has methods for checking these things.

 

 

Link to comment
Share on other sites

Link to post
Share on other sites

7 hours ago, Pinguinsan said:

Any time you use a reference type in Java for a class member , it will be null until it has been assigned using the new keyword. You must first initialize it, preferably in the constructor for your class.


import java.util.EmptyStackException;
import java.lang.Math;
import java.util.Stack;

public class RPNCalc {
	
	Stack<Double> st;
	double first; 
	double second;
	
	//Constructor for RPNCalc, called anytime a new RPNCalc is created with the new keyword, as you do in
	//the first line of Main
	public RPNCalc() {
		this.st = new Stack<Double>(); //Initialize member variable st to a new Stack<Double>() so it can be used
	}

	public static void main(String[] args) {
		RPNCalc test = new RPNCalc(); //Calls RPNCalc constructor
		test.push(1.0);
		System.out.println(test.getSize());
		System.out.println(test.pop());
	}
      
      	
	// place the number/argument on the top of the stack
	void push(double number) {
		st.push(number);
	}
      
 	// get size of stack
	int getSize() {
		
		Stack<Double> tmpStack = new Stack(); // create new temorary stack
		tmpStack = this.st; // set tmpStack to st
		
		int counter = 0;
		
		// iterate through the tmpStack until it is empty, and count elements
		while (true) {
			
			try {				
				tmpStack.pop(); 
			} catch (EmptyStackException e) {
				break; // break if stack is empty
			} catch (NullPointerException e) {
				break; // break if the stack is empty
			}
			counter++; // count the elements in the stack
		}
		
		return counter;
	}
  }

 

This solved the main issue - thanks.

7 hours ago, Unimportant said:

I'm not a java programmer but this looks fishy:


Stack<Double> tmpStack = new Stack(); // create new temorary stack
tmpStack = this.st; // set tmpStack to st

Surely it must be this.st = tmpStack ?

As it is now you lose the tmpStack you just created by overwriting it.

The point of the tmpStack is to be able to wreck it when I iterate through it. Popping something from the stack removes it, so I would have to ruin the stack I was getting the size of I wanted to count the elements. (I am not allowed to use the built-in getSize method in this exercise)

2 hours ago, SSL said:

 

Do not use exceptions to manage program control flow. The stack interface has methods for checking these things.

 

 

Thank you for the input, but this is an exercise where they want me to check of Exceptions. How would you rather implement that exact same method, if you were not to use the built-in method, nor exceptions?

Running Arch with i3-gaps on a Thinkpad X1 Extreme
Data Science Postgrad

 

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Claryn said:

This solved the main issue - thanks.

The point of the tmpStack is to be able to wreck it when I iterate through it. Popping something from the stack removes it, so I would have to ruin the stack I was getting the size of I wanted to count the elements. (I am not allowed to use the built-in getSize method in this exercise)

Thank you for the input, but this is an exercise where they want me to check of Exceptions. How would you rather implement that exact same method, if you were not to use the built-in method, nor exceptions?

 

I wouldn't. There is no way to do it without checking whether the stack is empty before popping. Exceptions should be used for checking for exceptional behavior, i.e. conditions that would not occur during normal program execution.

 

Part of the reason for that is because exceptions are relatively expensive in terms of runtime cost.

Link to comment
Share on other sites

Link to post
Share on other sites

3 hours ago, SSL said:

 

Do not use exceptions to manage program control flow. The stack interface has methods for checking these things.

 

 

I just copied his post and added the constructor, but you're correct.

Link to comment
Share on other sites

Link to post
Share on other sites

13 hours ago, SSL said:

 

I wouldn't. There is no way to do it without checking whether the stack is empty before popping. Exceptions should be used for checking for exceptional behavior, i.e. conditions that would not occur during normal program execution.

 

Part of the reason for that is because exceptions are relatively expensive in terms of runtime cost.

But how would you check if the stack is empty without using any of the built in functions? 

Running Arch with i3-gaps on a Thinkpad X1 Extreme
Data Science Postgrad

 

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, Claryn said:

But how would you check if the stack is empty without using any of the built in functions? 

You can't. That's why the built in functions are there.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

3 hours ago, fizzlesticks said:

You can't. That's why the built in functions are there.

Then Ill stick with the Exceptions. This exercise does not allow me to use built in functions like that.

Running Arch with i3-gaps on a Thinkpad X1 Extreme
Data Science Postgrad

 

Link to comment
Share on other sites

Link to post
Share on other sites

36 minutes ago, Claryn said:

Then Ill stick with the Exceptions. This exercise does not allow me to use built in functions like that.

 

Who's responsible for this "exercise"?

Link to comment
Share on other sites

Link to post
Share on other sites

16 hours ago, SSL said:

 

Who's responsible for this "exercise"?

My professor. We are to create an RPN-calculator with some specific behaviour. We are supposed to use a Stack to save the operands and the only built-in Stack-method we are allowed to use is Stack.push();

 

However, I am now facing a slightly different problem. You can see my implementation of the push-method above: When testing some simple behavior in the main-method:
 

	public static void main(String[] args) {
		
		RPNCalc test = new RPNCalc();
	
		test.push(1.0);
		test.push(5.0);
		test.push(4.0);
		test.push(2.0);
		test.push(3.0);
		System.out.println("Size: " + test.getSize());
		System.out.println(test.pop());
		System.out.println(test.pop());
		System.out.println(test.pop());
		System.out.println(test.pop());
		System.out.println(test.pop());
}

It gives the ouput:

Quote

Size: 6
NaN
NaN
NaN
NaN
NaN

Here are my getSize() and pop() methods:

	// return the first argument in the Stack, AND removes it. Returns Double.NaN if empty
	double pop() {
		try { 
			return st.pop(); // try to return double on top of stack, if empty return Double.NaN
		} catch (EmptyStackException e) {
			return Double.NaN;
		}
	}
	
	// get size of stack
	int getSize() {
		
		Stack<Double> tmpStack = new Stack(); // create new temorary stack
		tmpStack = this.st; // set tmpStack to st
		
		int counter = 1;
		
		// iterate through the tmpStack until it is empty, and count elements
		while (true) {
			
			try {				
				tmpStack.pop(); 
			} catch (EmptyStackException e) {
				break; // break if stack is empty
			} catch (NullPointerException e) {
				break; // break if the stack is empty
			}
			counter++; // count the elements in the stack
		}
		
		return counter;
	}

 

I also have the problem that if I run

System.out.println(this.getSize());

It always says that it is 1, and gives an EmptyStackException if i try to pop anything from it.

 

 

EDIT: Changed from tmpStack = this.st;

to tmpStack.equals(this.st); to solve first problem.
Second problem is still there. Whenever I call this.getSize(); or this.pop(); outside of the main-method, it returns 1 as the size and EmptyStackException on pop.

Running Arch with i3-gaps on a Thinkpad X1 Extreme
Data Science Postgrad

 

Link to comment
Share on other sites

Link to post
Share on other sites

5 hours ago, Claryn said:

EDIT: Changed from tmpStack = this.st;

to tmpStack.equals(this.st); to solve first problem.
Second problem is still there. Whenever I call this.getSize(); or this.pop(); outside of the main-method, it returns 1 as the size and EmptyStackException on pop.

All objects in Java are actually references, doing tmpStack = this.st doesn't copy the stack like you think it does. It makes tmpStack point to the same stack as this.st. So when you pop from tmpStack, you're also popping from this.st. This means that after you call getSize() you've already popped everything from the stack and it's now empty.

 

tmpStack.equals(this.st) is a comparison function, it checks if the 2 stacks are equal. It doesn't fix the problem, your getSize() method is now broken, it will always return 1.

 

You need to create a copy of the stack inside getSize(). There should be a method called copy or clone or something similar (I forget what Java calls it.) Also your counter should start at 0 not 1.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

3 hours ago, fizzlesticks said:

All objects in Java are actually references, doing tmpStack = this.st doesn't copy the stack like you think it does. It makes tmpStack point to the same stack as this.st. So when you pop from tmpStack, you're also popping from this.st. This means that after you call getSize() you've already popped everything from the stack and it's now empty.

 

tmpStack.equals(this.st) is a comparison function, it checks if the 2 stacks are equal. It doesn't fix the problem, your getSize() method is now broken, it will always return 1.

 

You need to create a copy of the stack inside getSize(). There should be a method called copy or clone or something similar (I forget what Java calls it.) Also your counter should start at 0 not 1.

Right, of course.

 

I solved the getSize() method by just having a global variable size that I make sure to add or subtract 1 to whenever I pop or push to the stack.

 

Running Arch with i3-gaps on a Thinkpad X1 Extreme
Data Science Postgrad

 

Link to comment
Share on other sites

Link to post
Share on other sites

Thank you all for the help. My RPN-calculator is done and scores 100% on the jUnit Test from the professor.

Here is the code if you are curious:

 

package encapsulation;

import java.util.EmptyStackException;
import java.lang.Math;
import java.util.Stack;
import java.util.Scanner;

public class RPNCalc {
	
	private Stack<Double> st;
	private int size;
	private double first; 
	private double second;
	
	public static void main(String[] args) {
		
		RPNCalc test = new RPNCalc();
		Scanner keyboard = new Scanner(System.in);
		String input = null;
		String operation = null;
		double operand;
		
		while (true) {
			System.out.println("Add operand (n) or add operation (o): ");
			input = keyboard.nextLine();
			
			if (input.equalsIgnoreCase("n")) {
				System.out.println("Operand: ");
				operand = keyboard.nextDouble();
				test.push(operand);
			} else if (input.equalsIgnoreCase("o")) {
				System.out.println("Operation (+,-,*,/,~,p,|): ");
				operation = keyboard.next(); 
				test.performOperation(operation.charAt(0));	
			} else {
				System.out.println("Invalid input!");
			}
		}
	}
	
	public RPNCalc() {
		this.st = new Stack<Double>();
	}
	
	// place the number/argument on the top of the stack
	public void push(double number) {
		st.push(number);
		size++; // increase size of stack
	}
	
	public String toString() {
		Stack<Double> tmpStack = new Stack(); // create new temporary stack
		tmpStack = (Stack<Double>) st.clone(); // clone st to tmpStack
		
		String s = "Stack: ";
		
		for (int i = 0; i < this.getSize(); i++) 
			s += tmpStack.pop() + ", ";
		return s;
	}
	
	// return the first argument in the Stack, AND removes it. Returns Double.NaN if empty
	public double pop() {
		try { 
			size--;
			return st.pop(); // try to return double on top of stack, if empty return Double.NaN
		} catch (EmptyStackException e) {
			return Double.NaN;
		}
	}
	
	// returns the argument at index. Returns Double.NaN if empty
	public double peek(int index) {
		
		Stack<Double> tmpStack = new Stack(); // create new temporary stack
		tmpStack = (Stack<Double>) st.clone(); // set tmpStack to st
		if (index < 0)
			return Double.NaN;
		
		for (int i = 0; i < index; i++) { // remove elements in tmpStack up to index
			try {			
				tmpStack.pop();
			} catch (EmptyStackException e) { // return Double.NaN if index is empty
				return Double.NaN;
			} catch (IndexOutOfBoundsException e) { // return Double.NaN if index is out of bounds
				return Double.NaN;
			}
		}
		
		return tmpStack.pop();
	}
	
	// get size of stack
	public int getSize() {
		return size;
	}
	
	// perform operation on two top arguments in stack, AND removes them - replaced with
	// the calculated value
	public void performOperation(char operation) {
		
		// check operation and do the assigned mathemtical operation
		switch (operation) {
		case '*':
			popOperands(operation);
			push(first*second);
			break;
		case '/':
			popOperands(operation);
			push(second/first);
			break;
		case '+': 
			popOperands(operation);
			push(first+second);
			break;
		case '-':
			popOperands(operation);
			push(second-first);
			break;
		case '~':
			popOperands(operation);
			push(first);
			push(second);
			break;
		case '|':
			popOperands(operation);
			push(Math.abs(first));
			
		case 'p':
			popOperands(operation);
			push(Math.PI);
			break;	
		}
	}
	
	private void popOperands(char operation) {
		
		// grab the two first elemts in the stack
		if (operation == '|') {			
			first = pop();
		} else if (operation == 'p') {
			// do nothing	
		} else {
			first = pop();
			second = pop(); 
		}
	}	
}

Main-method is just for testing behavior.

Running Arch with i3-gaps on a Thinkpad X1 Extreme
Data Science Postgrad

 

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×