Stack pop方法导致空指针异常

时间:2012-03-12 01:16:30

标签: java stack nullpointerexception

我刚刚实现了一个循环,用卡(从堆栈)填充玩家的手(队列),但我在LinkedStack.pop()遇到NullPointerException。我没有改变提供的LinkedStack代码,我已经检查了甲板上是否填充了元素,所以我无法立即看到NullPointerException的来源。下面是我的代码段和错误输出。如果您需要任何其他代码,请告诉我。

(SimpleUnoGame.java)

45    LinkedQueue<UnoCard> cardHand = new LinkedQueue<UnoCard>();
46    //draw cards for player
47    for(int j = 0; j < INITIAL_CARDS; j++) {
48        cardHand.enqueue(faceDownCards.pop());
49    }
50    newPlayer.setCards(cardHand);
51    playerCollection.enqueue(newPlayer);

(LinkedStack.pop())

43    T result = top.getElement();
44    top = top.getNext();
45    count--;
46    return result;

(例外)

Exception in thread "main" java.lang.NullPointerException
    at LinkedStack.pop(LinkedStack.java:43)
    at SimpleUnoGame.<init>(SimpleUnoGame.java:48)

根据要求,这是完整的代码:

(LinkedStack.java)

/**
 * Represents a linked implementation of a stack
 */

public class LinkedStack<T> implements StackADT<T> {
    //indicates number of elements stored
    private int count;  
    //pointer to top of stack
    private LinearNode<T> top; 

    /**
     * Creates an empty stack
     */
    public LinkedStack() {
        count = 0;
        top = null;
    }

    /**
     * Adds the specified element to the top of this stack
     * @param element element to be pushed on stack
     */
    public void push(T element) {
        LinearNode<T> temp = new LinearNode<T>(element);

        temp.setNext(top);
        top = temp;
        count++;
    }

    /**
     * Removes the element at the top of this stack and returns a reference to it
     * Throws an EmptyCollectionException if the stack is empty
     * @return T element from top of stack
     * @throws EmptyCollectionException on pop from empty stack
     */
    public T pop() throws EmptyCollectionException {
        if (isEmpty()) {
            throw new EmptyCollectionException("Stack");
        }

        T result = top.getElement();
        top = top.getNext();
        count--;

        return result;
    }

    /**
     * Returns a reference to the element at the top of this stack
     * Throws an EmptyCollectionException if the stack is empty
     * (the element is not removed from the stack)
     * @return T element on top of stack
     * @throws EmptyCollectionException on peek at empty stack  
     */
    public T peek() throws EmptyCollectionException {
        if (isEmpty()) {
            throw new EmptyCollectionException("Stack"); 
        }

        return top.getElement();
    }

    /**
     * Returns true if this stack is empty and false otherwise
     * @return boolean true if stack is empty
     */
    public boolean isEmpty() {
        if (count == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Returns the number of elements in this stack
     * @return int number of elements in this stack
     */
    public int size() {
        return count;
    }

    /**
     * Returns a string representation of this stack
     * @return String representation of this stack
     */
    public String toString() {
        String output = "";
        T result;

        for (int i = 0; i < this.size(); i++) {
            result = top.getElement();
            output = output + result;
            top = top.getNext();
        }

        return output;
    }
}

(SimpleUnoGame.java)

public class SimpleUnoGame {

    private final int INITIAL_CARDS = 7;
    private LinkedQueue<UnoPlayer> playerCollection = new LinkedQueue<UnoPlayer>();
    private LinkedStack<UnoCard> faceUpCards = new LinkedStack<UnoCard>();
    private LinkedStack<UnoCard> faceDownCards = new LinkedStack<UnoCard>();
    private int cardCount = 0;

    public SimpleUnoGame(int numberOfPlayers, int highestRank) {
        //create cards and add to faceDownCards
        for(int i = 1; i <= highestRank; i++) {
            for(int j = 0; j <= 1; j++) {
                //blue cards
                UnoCard cardB = new UnoCard('B', i);
                faceDownCards.push(cardB);
                //green cards
                UnoCard cardG = new UnoCard('G', i);
                faceDownCards.push(cardG);
                //red cards
                UnoCard cardR = new UnoCard('R', i);
                faceDownCards.push(cardR);
                //yellow cards
                UnoCard cardY = new UnoCard('Y', i);
                faceDownCards.push(cardY);
            }
        }

    System.out.println("Cards: " + faceDownCards.toString());  //debug check

    //shuffle cards randomly
    shuffleCards(faceDownCards);

    System.out.println("Cards: " + faceDownCards.toString());  //debug check

    //create players and add to playerCollection
    for (int i = 0; i < numberOfPlayers; i++) {
        //ask for name
        String name = "Taylor";

        UnoPlayer newPlayer = new UnoPlayer(name);
        LinkedQueue<UnoCard> cardHand = new LinkedQueue<UnoCard>();

        //draw cards for player
        for(int j = 0; j < INITIAL_CARDS; j++) {
            cardHand.enqueue(faceDownCards.pop()); //PROBLEM OCCURS HERE
        }

        newPlayer.setCards(cardHand);
        playerCollection.enqueue(newPlayer);
    }

    System.out.println("There are " + numberOfPlayers + " players in the game.");
    System.out.println(playerCollection.toString());  //debug check

    //draw one face up card
    faceUpCards.push(faceDownCards.pop());
}

1 个答案:

答案 0 :(得分:2)

您的顶部变量为空。你如何初始化它?

在您的代码示例中,您似乎在构造对象时将 top 设置为null,然后在推送项目时将其设置为非null值。

如果是这种情况,那么您似乎没有将某些东西推入LinkedStack。

虽然我必须承认我无法弄清楚确切的问题,因为你只提供了一些代码,而且它没有多大意义。

修改

方法toString()修改顶部字段,该字段应该保留队列的头部。调用toString方法应该没有副作用。将其更改为:

public String toString() {
    String output = "";
    T result;
    LinearNode<T> tempHead = top;

    for (int i = 0; i < this.size(); i++) {
        result = tempHead.getElement();
        output = output + result;
        tempHead = tempHead.getNext();
    }

    return output;
}

我不知道是谁为你写了这门课,但这是一个新手的错误。通过调用toString(),您实际上是在清空队列。