简体   繁体   中英

Java - doubly Linked list (deep) copy constructor

As part of my assignment, we have been asked to create a constructor that will do a deep copy of another list. Below is how it has been described to us.

Copy constructor: implement a copy constructor accepting a DSList object. The copy constructor should perform a deep copy of the DSList passed to the constructor: the new DSList should not contain references to the Node objects in the second DSList. (The two DSLists should be independent: changing the contents of Node objects in one DSList should not affect the other).

Can you guys please help me with the copy constructor? I don't know how to write this.

Any insight provided will be much appreciated. Thanks.

Below is the first part of the DSList class.

public class DSList implements List {
    public Node head;

    /**
     * This is a constructor of the DSList class. 
     * The constructor takes no parameters.
     */
    public DSList() {       
    }

    /**
     * This is a constructor of the DSList class. 
     * The constructor takes in one parameter and 
     * set this to the given node. 
     * @param head_ is the given node.
     */
    public DSList(Node head_) {     
        this.head = head_;
    }

    /**
     * This is the copy constructor. The constructor takes in another DSList object and copy it to
     * a new DSList. Each copy created is independent of the original DSList.
     * @param other is another DSList object.
     */
    public DSList(DSList other) { // Copy constructor. 
        // this needs to be filled///
    }

Apart from this, we have been provided separate Node class and a Token class (shown below).

public class Node {
    public Node next;
    public Node prev;
    private Token t;

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

    public Token getToken() {
        return t;
    }

    @Override
    public boolean equals(Object other) {
        if (this == other)
            return true;
        if (other == null)
            return false;
        if (!(other instanceof Node))
            return false;

        return t.equals(((Node)other).getToken());
    }

    @Override
    public int hashCode() {
        if ( t == null )
            return 0;
        return t.hashCode();
    }
}

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 String getOperator() {
        return operator;
    }

    public double getOperand() {
        return operand;
    }

    public int getPrecedence() {
        if ( type == Type.PAREN )
            return -1;
        if ( type != Type.OPERATOR )
            return 0;
        
        switch ( operator ) {
        case "+":
        case "-":
            return 0;
        case "*":
        case "/":
            return 2;
        }
        return 0;
    }
    
    @Override
    public boolean equals(Object obj) {
        if ( obj == null )
            return false;
        if ( obj == this )
            return false;
        if ( !obj.getClass().equals(Token.class)) 
            return false;
        
        Token t = (Token)obj;
        if ( t.type == this.type ) {
            if ( this.type == Type.OPERATOR )
                return operator.equals(t.operator);
            else
                return operand == t.operand;
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        return 0;
    }
    
    public String toString() {
        return this.type == Type.OPERAND ? "" + this.operand : this.operator;
    }
}

The constructor with the signature public Token(Token other) is a great example of a copy constructor. The constructor is called and then the other Token's members are set to be equal to that of the new Token's members.

You have a DSList that is made up of many nodes linked together. If you want to copy all of these nodes, then you must create a new empty DSList. This DSList is going to contain all copies of the nodes from the original DSList. Next, you will want to iterate over all Nodes in the original DSList, copy the Nodes by calling a copy constructor on each Node, and then insert those Nodes into the new DSList. This means you will to call a copy constructor on Token and Node since DSList contains references to Node and Node contains references to Token. After completing this process, the new DSList will be a deep copy version of the original.

The code will end up looking something like this.

public DSList(DSList original)
{
    DSList newListCopy = new DSList();
    if (this.head != null)
    {
        // Call the copy constructor for the head node and save the head for the new list.
        newListCopy.head = new Node(this.head);
        // Temporary variables for inserting and iterating lists.
        Node newLinkedNode = newListCopy.head;
        Node iterator = this.head.next;
        // Looping through the lists.
        while (iterator != null)
        {
            // Insert the copy of the node from the other list.
            Node prev = newLinkedNode;
            newLinkedNode.next = new Node(iterator);
            newLinkedNode = newLinkedNode.next;
            newLinkedNode.prev = prev;
            iterator = iterator.next;
        }
    }
    return newListCopy;
}

A key insight is that if you have objects, you must copy them by creating a new instance of that object with new. You need copy constructors like the one in token for all objects that are part of the object you wish to copy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM