2010-10-30 65 views
0

作爲第一年任務的一部分,我需要創建一個類,該類使用提供的鏈表實現來實現提供的堆棧接口,然後由另一個提供的類。我能夠使用我自己的LL輕鬆完成任務;然而,我被告知我需要使用提供的那個。java中的空指針異常需要幫助

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

現在我每次嘗試運行它時都會收到空指針異常。我認爲這是由於測試人員在LL初始化之前嘗試獲取列表的大小而引起的,但似乎並非如此,我很難過。

關於我能做些什麼來解決這個錯誤,以便我可以交出剩下的任務?謝謝:)

所提供的鏈接列表實現

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); 
    } 
} 

我實現

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; 
     } 
    } 
} 

提供的界面

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); 
    } 
} 

測試機

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); 
    } 
} 
+3

在用,你會看到它發生就行了NullPointerException異常。這將幫助您和我們解決問題:) – Cristian 2010-10-30 05:49:19

+1

http://techblog.bozho.net/?p=155 – Bozho 2010-10-30 05:53:02

+0

感謝您的鏈接。不幸的是,通過列出的步驟使我對於實際出現的問題更加無知。計數應該初始化爲0,所以它不應該指向空值。我嘗試使用空指針異常來捕獲此案例;然而,我只是結束了另一個空指針錯誤。 – Pax 2010-10-30 06:44:59

回答

3

您在StackLL中有private LinkedList values;

這就是說「這個班級有一個LinkedList類型的字段叫values」。它不會將對象分配給values,因此當您嘗試訪問它時,會發生NullPointerException。

您應該能夠通過向values分配一個值來修復它,即:

private LinkedList values = new LinkedList();

(我不知道你是否已經瞭解泛型還,但如果你有,記得添加類型,例如LinkedList<Person>。)

1

看在錯誤消息中給定的代碼行(我假設你的size()函數中有return語句)並且認爲a回答NullPointerException的含義 - 空的變量尚未初始化。然後問自己,我是否希望這個變量在這裏被初始化?如果是,那麼問爲什麼不是它以及它應該在哪裏初始化?如果不是,那麼你在給定的位置有一個邏輯錯誤。

+0

不知道我跟隨你來自哪裏。生成錯誤消息的代碼行是測試器類中的初始檢查以查找鏈接列表的大小;但是,我無法更改此代碼。我曾嘗試在StackLL大小函數中使用try catch塊,但我仍然得到空指針異常。 – Pax 2010-10-30 06:32:24

+0

我試着通讀代碼,唯一想到的是由於某些原因「私人LinkedList值」未初始化。我不明白爲什麼。 – Pax 2010-10-30 07:12:17

+0

值**被**初始化爲默認值(null)。在* size()*方法中,您正在對空對象調用方法,因此爲空指針異常。 – diciu 2010-10-30 07:32:38

0

您沒有在StackLL中實例化LinkedList對象。因此,您第一次嘗試訪問它時,會觸發NPE。