堆栈复制构造函数

Stack copy constructor

我的堆栈复制构造函数有很多困难。 DSStack 扩展了 Stack 抽象 class 并使用双向链表来存储数据(令牌)。它在构造函数的 this.push(oldListNode.getToken()); 行一直失败(NullPointerException)。我已经包含了我认为有助于解决我的问题的 methods/classes。它需要是 deep 副本。任何帮助或指导都会很棒。

public class DSStack extends Stack {

    // The list containing the data
    private DSList theStack;

    // Constuct an empty stack using a LinkedList as the container
    public DSStack() {
        theStack = new DSList();
    }

    public DSStack(DSStack other) {
    // Create a reference for the stack to be copied
    Node oldListNode = other.theStack.head;

    while (oldListNode != null) {
        this.push(oldListNode.getToken());
        oldListNode = oldListNode.next;
        }
    }

    /**
     * Adds the given object to the top of the Stack. 
     * @return The given object. 
     */
    public Token push(Token obj) {      
        theStack.add(obj);
        return obj;
    }
}

public class DSList implements List {

    /**
     * Appends the specified element to the end of this list.
     * @param obj The object to add. 
     * @return True if the object has been added to the list. 
     * 
     * @throws NullPointerException if the specified object is null.
     */
    public boolean add(Token obj) {
        if (obj == null) {
            throw new NullPointerException();
        }
        // If list is empty, add new node to front.
        if(isEmpty()) {  
            // Create a new Node. Add Token obj as data
            Node newNode = new Node(null, null, obj);  
            // point head to new Node, newNode
            head = newNode;
            return true;
        } else { 
            // create a reference of the start position in the list
            Node current = head;
            // While there are nodes remaining in the list, advance through to reach the end.
            while (current.next != null) 
                current = current.next;
            // Create a new node and append it to the end of the list, with 'prev' pointing to current (2nd to last node)
            Node newNode = new Node(null, current, obj);
            // Point 2nd to last element to the newest , last node in the list (in next variable)
            current.next = newNode;
            // Return true if successful addition of node.
            return true;
        }
    }
 }

public class Node {

    public Node next;
    public Node prev;

    // data being stored in each node
    private Token t;

    // Node constructor
    public Node(Node next, Node prev, Token token) {
        this.next = next;
        this.prev = prev;
        this.t = token;
    }

    public Token getToken() {
        return t;
    }
}

public class Token {

    public enum Type { OPERATOR, OPERAND, PAREN };
    public Type type;

    private String operator;
    private double operand;

    public Token(double result) {
        this.operand = result;
        this.type = Type.OPERAND;
    }

    public Token(String op) {
        this.operator = op;
        this.type = Type.OPERATOR;

        if ( this.operator.equals("(") || this.operator.equals(")") ) {
            this.type = Type.PAREN;
        }
    }

    public Token(Token other) {
        this.operator = other.operator;
        this.operand = other.operand;
        this.type = other.type;
    }
}

您必须在参数化构造函数 public DSStack(DSStack other) 中初始化 theStack。我没有看到发生这种情况,因此它仍然包含使用参数化构造函数构造的任何对象的空值。请注意,我说的是您的 push 方法

中的 theStack 引用

编写构造函数有时可能是一件艺术品。您所要做的就是

public DSStack()
{
    theStack = new DSList();
}

public DSStack( DSStack other )
{
    this();
    // Rest of the code goes on 
    // Create a reference for the stack to be copied
    Node oldListNode = other.theStack.head;

    while (oldListNode != null) 
    {
        this.push(oldListNode.getToken());
        oldListNode = oldListNode.next;
    }

}

这将确保您始终初始化 theStack 变量,无论您初始化哪个构造函数来为 DSStack 对象分配内存。 this() 语句实际上调用了 no-arg 构造函数,您在其中初始化了 theStack 变量