0

Trying to convert the arrays of an old program into generic arrays. This is the first time I've worked with generics, and I'm clearly missing something here. I'm getting an NPE when trying to push characters of a string into some dedicated stacks. I've printed the length of the arrays initialized in the evaluateExpression method and get 0.

How am I flubbing this initialization? Are my constructors not appropriate to setting each array's capacity? Am I not calling things into scope properly in main?

I've indicated in the code where I'm getting my first NPE on line 33. Other comments and rest of program is probably irrelevant. I'm not concerned if the program functions like it's supposed to, just these generic arrays.

package generics;

import java.util.Scanner; 

public class GenericTesting<E> {

/**
 * function converts input expression to a char array, 
 * which is then parsed and its elements pushed into int and char arrays
 * while spaces are collected and separated from what will be equated
 * @param expression prefix expression entered by user
 */
public static int evaluateExpression(String expression) {
    int result = 0; 

    char[] tokens = expression.toCharArray();
    StackG<Integer> operands = new StackG<>(10); 
    StackG<Character> operators = new StackG<>(10); 
    StackG<Character> blanks = new StackG<>(10);

    for (int i = tokens.length -1; i > 0; i--) {
        if (tokens[i] == ' ') 
            blanks.push(tokens[i]);
        if (tokens[i] >= '0' && tokens[i] <= '9') 
            operands.push(tokens[i]); 
        if (tokens[i] == '*' || tokens[i] == '+' || tokens[i] == '-')
            operators.push(tokens[i]); 
    }

    while (operands.getLength() != 1) {
        int num1 = operands.pop();     // null pointer exception
        int num2 = operands.pop(); 

        char symbol = operators.pop(); 
        if (symbol == '*')
            result = num1 * num2; 
        if (symbol == '+');
            result = num1 + num2; 
        if (symbol == '-')
            if (num1 > num2)
                result = num1 - num2; 
            else 
                result = num2 - num1; 
    }
    return result; 
}

Array Constructors, push and pop functions:

public class StackG<E>{
    private E[] stack;     // holds stack elements 
    private E[] stack2;    // holds stack elements while stack is resized
    private int capacity;  // number of elements that can be stored
    private int length;    // number of currently stored elements
    private static int top;       // stack top pointer

public StackG(int initialCapacity) {
    capacity = initialCapacity; 
    stack = (E[]) new Object[capacity];  
    length = 0; 
    top = 0;
}

public StackG() {
    capacity = 5; 
    stack = (E[]) new Object[capacity]; 
    length = 0; 
    top = 0; 
}

public void push(Object item) {
    if (top == stack.length)
        throw new IllegalArgumentException(); //Stack is full
    else {
        stack[top] = (E) item; 
        top++;
        length++;
    }
}

public E pop() {
    if (isEmpty())
        throw new IllegalArgumentException(); //Stack is empty
    else {
        top--;
        length--;
        return stack[top]; 
    } 
}

Client Code:

    public static void main(String[] args) {

    Scanner keyboard = new Scanner(System.in); 

    System.out.print("Enter a prefix expression "
            + "using only *, +, and - operators and positive operands: ");
    String expression = keyboard.nextLine(); 
    int result = evaluateExpression(expression);

    System.out.println(result);
}
  • So, *obviously* `operands.getLength()` is 0, and the `!= 1` check in the `while` loop should probably be `> 1`. – Andreas Aug 08 '16 at 03:34
  • What `String` are you passing to `evaluateExpression` when you get the NPE? Note, you're traversing the string in reverse, and stopping before the first character - don't know if this is causing your problem. You're also being a bit cavalier with converting `char` to `Integer`. The default way that this works is probably not what you want. – Dawood ibn Kareem Aug 08 '16 at 03:34
  • My best advice would be to step through this with a debugger, to see exactly what's going wrong. It's actually a whole bunch of little errors, not one big one. – Dawood ibn Kareem Aug 08 '16 at 03:35
  • Why are you implementing your own stack? Use a [`Deque`](https://docs.oracle.com/javase/7/docs/api/java/util/Deque.html), e.g. an [`ArrayDeque`](https://docs.oracle.com/javase/7/docs/api/java/util/ArrayDeque.html). Quoting javadoc: *Deques can also be used as LIFO (Last-In-First-Out) stacks. This interface should be used in preference to the legacy `Stack` class.* – Andreas Aug 08 '16 at 03:36
  • Did you perhaps forget to push `result` back on the `operands` stack? --- You also have a very weird definition of the minus operator. `3 - 5 = 2`? Normally, `3 - 5 = -2`. – Andreas Aug 08 '16 at 03:42

0 Answers0