简体   繁体   中英

Java - creating Object without change the Original one

would it be possible to create new Object with the attributes from the Original Object without changing it ?

For example :

public void exampleTests() {
        Tree t = Trees.makeTree(new int[]{2, 3, 4, 4, 1});//creating tree
        assertTrue(t.contains(4)); //check if 4 is a node
        assertFalse(t.contains(6));//check if 6 is a node
        assertEquals(4, t.size()); //return size-nodes number (only different digits)

        Tree t2 = t.add(6).add(7).add(6); // obj 2 take obj 1 and add 6 and 7 to it
        assertFalse(t.contains(6)); // the first object should have no 6
        assertTrue(t2.contains(6)); // the second object should have 6

Trees class :

public  class Trees  {

    public  static Tree makeTree(int[] elements) {

        Tree tree = new Nodes();
        for (int i : elements) {
            tree.add(i);
        }
        return tree;
    }

}

Tree interface

public interface Tree {


    public  Tree add(int i);

    public boolean contains(int i);

    public int size();

    public String elementsAsString();

Node Class :

public class Node  {
    int i;
    Node left;
    Node right;

    public Node(int data) {
        this.i = data;
        left = null;
        right = null;
    }
}

Nodes class :

public class Nodes implements Tree {


    private    Node root;

    public Nodes() {
        this.root = null;
    }

    @Override
     public Nodes add(int i) {
        root = insertNode(root, new Node(i));
        return new Nodes();
    }

     private Node insertNode(Node currentParent, Node newNode) {

        if (currentParent == null) {
            return newNode;
        } else if (newNode.i > currentParent.i) {
            currentParent.right = insertNode(currentParent.right, newNode);
        } else if (newNode.i < currentParent.i) {
            currentParent.left = insertNode(currentParent.left, newNode);
        }
        return currentParent;
    }

what do we call this in Java terms ?

You would need to create a copy of the original object.

One way to do it is with a copy constructor :

public Tree (Tree other) {
    // copy all the properties of other to the new object
}

Then change

Tree t2 = t.add(6).add(7).add(6);

to

Tree t2 = new Tree(t).add(6).add(7).add(6); 

Note that if the members of Tree include reference types (ie references to other objects), you must decide whether to create new copies of these objects too. If you copy just the references, you'll get a shallow copy of the original object, which could cause problems.

EDIT:

Since it appears Tree is an interface, you'll have to create a copy constructor in the class that implements it:

public Nodes (Tree other) {
    // copy all the properties of other to the new object
}

Then you can create the copy directly:

Tree t2 = new Nodes(t).add(6).add(7).add(6); 

or via a factory method:

Tree t2 = Trees.makeTree(t).add(6).add(7).add(6);

where makeTree is:

public  static Tree makeTree(Tree source) {

    Tree tree = new Nodes(source);
    return tree;
}

Note that public Nodes (Tree other) is not exactly a copy constructor now - it's more general than a copy constructor, since it can accept any implementation of the Tree interface and create a new Nodes instance that contains the same data.

You would implement Tree as immutable (meaning a once instantiated object can not be changed) and create a new instance in add:

public Tree add(int node) {
    // highly inefficient, assuming nodes are internally stored as an int array
    // allocate new array + 1 size
    int[] nodes = new int[this.nodes.length + 1];
    // copy this tree's nodes
    System.arraycopy(this.nodes, 0, nodes, 0, this.nodes.length);
    // add new node
    nodes[nodes.length - 1] = node;
    // return new tree instance
    return new Tree(nodes);
}

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