【问题标题】:Stack copy constructor堆栈复制构造函数
【发布时间】:2017-04-06 16:10:11
【问题描述】:

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

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

【问题讨论】:

  • 假设答案是正确的,这意味着堆栈跟踪比您告诉我们的要多(异常来了,不是直接来自复制构造函数,而是来自push。)如果您包含此类信息,我们更容易看到发生了什么。

标签: java stack copy-constructor doubly-linked-list deep-copy


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    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() 语句实际上调用了您初始化 theStack 变量的 no-arg 构造函数

    【讨论】:

    • 谢谢,这解决了我的问题。
    猜你喜欢
    • 1970-01-01
    • 2013-04-29
    • 1970-01-01
    • 2017-03-27
    • 1970-01-01
    • 2014-06-17
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    相关资源
    最近更新 更多