tags:

views:

121

answers:

3

As a portion of a first year assignment, I need to create a class which uses a provided linked list implementation to implement a provided stack interface which is then tested by another provided class. I was able to easily complete the assignment using my own LL; however, I was told that I needed to use the one provided.

Exception in thread "main" java.lang.NullPointerException
    at StackLL.<init>(StackLL.java:21)
    at StackTester.main(StackTester.java:91)

Now I get null pointer exceptions whenever I try and run it. I thought this was being caused by the tester trying to grab the size of the list before the LL is initialized, but that doesn't seem to be the case and I am stumped.

Any tips on what I can do to fix the bug so that I can hand in the rest of the assignment? Thanks :)

The provided linked list implementation

LinkedList.java

/**
 * LinkedList - a simple linked list of ints 
 */
public class LinkedList 
{
    Node head;
    int count;

    public LinkedList ()
    {
        head = null;
        count = 0;
    }

    /**
     * Adds the given item to the start of the list
     */
    public void addToStart (int item)
    {
        Node newNode = new Node();
        newNode.value = item;

        if (head != null)
            newNode.next = head;

        head = newNode;
        count++;
    }

    /**
     * Adds the given item to the end of the list
     */
    public void addToEnd (int item)
    {
        if (size() == 0)
        {
            addToStart (item);
        }
        else
        {
            Node n = head;
            while (n.next != null)
                n = n.next;

            n.next = new Node(item);
            count++;
        }
    }

    /**
     * Remove and return the first item in the list
     */
    public int removeFromStart ()
    {
        if (size() == 0)
            throw new EmptyListException();

        int valtoReturn = head.value;
        head = head.next;
        count--;
        return valtoReturn;
    }

    /**
     * Remove and return the last item in the list
     */
    public int removeFromEnd ()
    {
        if (size() == 0)
            throw new EmptyListException();
        if (size() == 1)
            return removeFromStart();
        else
        {
            Node n = head;
            while (n.next.next != null)
                n = n.next;

            int valtoReturn = n.next.value;
            n.next = null;
            count--;
            return valtoReturn;
        }
    }

    /**
     * Return the number of items contained in this list
     */
    public int size ()
    {
        return count;
    }

    /**
     * A basic node class
     */
    private class Node
    {
        int value;
        Node next;

        Node()
        {
        }

        Node (int value)
        {
            this.value = value;
        }
    }

    // random testing code for the Linked List
    public static void main (String [] args)
    {
        LinkedList l = new LinkedList();

        l.addToStart (5);
        int val = l.removeFromStart();
        System.out.println (val == 5 ? "passed" : "failed");

        System.out.println (l.size() == 0 ? "passed" : "failed");

        for (int x = 0; x < 10; x++)
            l.addToEnd (x);

        System.out.println (l.size() == 10 ? "passed" : "failed");
        while (l.size() > 0)
            System.out.print (l.removeFromEnd() + " ");
        System.out.println ();
    }
}

/**
 * The exception class when a removal action is performed on
 *  an empty list.
 */
class EmptyListException extends RuntimeException 
{
    public EmptyListException ()
    {
        super();
    }

    public EmptyListException (String s)
    {
        super(s);
    }
}

My implementation

StackLL.java

/**
 * A linked list implementation of the Stack ADT.
 *
 */

public class StackLL implements Stack
{
    // The linked list that will contain the values in the stack
    private LinkedList values;

    public int size()
    {
        return values.size();
    }

    public boolean isEmpty()
    {
        if (values.size() <= 0) {
            return true;
        }
        return false;
    }

    public void push(int element)
    {
        values.addToStart(element);
    }

    public int pop() throws StackEmptyException
    {
        if (values.size() == 0) {
            throw new StackEmptyException();
        }
        else {
            return values.removeFromStart();
        }
    }
    public int peek() throws StackEmptyException
    {
        if (values.size() == 0) {
            throw new StackEmptyException();
        }
        else { //This is a pretty silly way to do this, but I can't think of any other way without making my own linked list method.
            int elementVal = values.removeFromStart();
            values.addToStart(elementVal);
            return elementVal;
        }
    }
}

The Provided Interface

Stack.java

/**
 * Stack.java
 *
 * A specification of the Stack ADT
 *
 */
public interface Stack
{
    int size();
    boolean isEmpty();
    void push (int element);
    int pop() throws StackEmptyException;
    int peek() throws StackEmptyException;
}

class StackEmptyException extends Exception
{
    public StackEmptyException ()
    {
        super();
    }

    public StackEmptyException (String s)
    {
        super(s);
    }
}

The Tester

StackTester.java

    /**
 * StackTester.java
 *
 * Some test cases for a stack.
 */
public class StackTester
{
    public static void testOne (Stack s)
    {
        try
        {
            if (s.size() != 0 || !s.isEmpty())
                System.out.println("1: Failed size or isEmpty.");
            s.push(1);
            s.push(2);

            if (s.size() != 2 || s.isEmpty())
                System.out.println("2: Failed size or isEmpty.");

            if (!(s.pop() == 2))
                System.out.println("3: Failed pop");

            if (!(s.peek() == 1))
                System.out.println("4: Failed peek");

            if (!(s.pop() == 1))
                System.out.println("5: Failed pop");

            if (s.size() != 0 || !s.isEmpty() )
                System.out.println("6: Failed size or isEmpty.");
        }
        catch (StackEmptyException e)
        {
            System.out.println(e);
        }   
    }

    public static void testTwo (Stack s)
    {
        try
        {       
            for (int i = 0; i < 100; i++)
            {
                s.push(i);
            }

            if (s.size() != 100)
                System.out.println("7: Failed size.");

            for (int i = 99; i >= 0; i--)
            {
                if (!(s.pop() == i))
                {
                    System.out.println("Failed pop for: " + i);
                    break;
                }   
            }
        }
        catch (StackEmptyException e)
        {
            System.out.println("Failed testTwo.");
            System.out.println(e);
        }   
    }

    public static void testThree (Stack s)
    {
        try {
            while (!s.isEmpty())
                s.pop();
        }
        catch (StackEmptyException e) {
            System.out.println ("Failed empty stack test (popped on a non empty stack threw exception)");
        }

        try
        {
            s.pop();
            System.out.println("Failed empty stack test.");
        }
        catch (StackEmptyException e)
        {
            /* If we get here, we 
             * passed the previous test.
             */
        }
    }

    public static void main (String args[])
    {
        Stack s1 = new StackLL();
        Stack s2 = new StackLL();
        Stack s3 = new StackLL();

        testOne(s1);
        testTwo(s2);
        testThree(s3);
    }
}
+1  A: 

Look at the line of code given in the error message (I'm assuming its the return statement in your size() function) and think about the meaning of NullPointerException -- the variable which is null is not yet initialized. Then ask yourself, do I expect this variable to be initialized here? If yes, then ask why isn't it and where should it be initialized? If no, then you have a logic error at the given location.

heavyd
Not sure I follow where your coming from. The line of code which is generating the error message is the initial check in the tester class to find the size of the linked list; however, I cannot change this code. I have tried use a try catch block in the StackLL size function, but I still got the null pointer exception.
Ive tried reading through the code and the only thing that comes to mind is that for some reason "private LinkedList values" isn't initializing. I have no clue why though.
values **is** initialized to the default value (null). In the *size()* method, you're calling a method on a null object, hence the null pointer exception.
diciu
+2  A: 

You have private LinkedList values; in StackLL.

That says "this class has a field called values of type LinkedList". It does not assign an object to values, so when you try to access it, a NullPointerException occurs.

You should be able to fix it by assigning a value to values, i.e.:

private LinkedList values = new LinkedList();

(I don't know if you've learned about generics yet, but if you have, remember to add the type, e.g. LinkedList<Person>.)

Coronatus
A: 

You aren't ever instantiating a LinkedList object in StackLL. So the first time you try to access it, it blows a NPE.

Eric Bowman - abstracto -