是否可以使用原始对象的属性创建新的Object而无需更改它?
例如 :
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
Run Code Online (Sandbox Code Playgroud)
树类:
public class Trees {
public static Tree makeTree(int[] elements) {
Tree tree = new Nodes();
for (int i : elements) {
tree.add(i);
}
return tree;
}
}
Run Code Online (Sandbox Code Playgroud)
树界面
public interface Tree {
public Tree add(int i);
public boolean contains(int i);
public int size();
public String elementsAsString();
Run Code Online (Sandbox Code Playgroud)
节点类:
public class Node {
int i;
Node left;
Node right;
public Node(int data) {
this.i = data;
left = null;
right = null;
}
}
Run Code Online (Sandbox Code Playgroud)
节点类:
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;
}
Run Code Online (Sandbox Code Playgroud)
我们用Java术语称之为什么?
您需要创建原始对象的副本.
一种方法是使用复制构造函数:
public Tree (Tree other) {
// copy all the properties of other to the new object
}
Run Code Online (Sandbox Code Playgroud)
然后改变
Tree t2 = t.add(6).add(7).add(6);
Run Code Online (Sandbox Code Playgroud)
至
Tree t2 = new Tree(t).add(6).add(7).add(6);
Run Code Online (Sandbox Code Playgroud)
请注意,如果Tree包含引用类型的成员(即对其他对象的引用),则必须决定是否也创建这些对象的新副本.如果只复制引用,则会得到原始对象的浅表副本,这可能会导致问题.
编辑:
由于它看起来Tree是一个接口,你必须在实现它的类中创建一个复制构造函数:
public Nodes (Tree other) {
// copy all the properties of other to the new object
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以直接创建副本:
Tree t2 = new Nodes(t).add(6).add(7).add(6);
Run Code Online (Sandbox Code Playgroud)
或通过工厂方法:
Tree t2 = Trees.makeTree(t).add(6).add(7).add(6);
Run Code Online (Sandbox Code Playgroud)
在哪里makeTree:
public static Tree makeTree(Tree source) {
Tree tree = new Nodes(source);
return tree;
}
Run Code Online (Sandbox Code Playgroud)
请注意,public Nodes (Tree other)它现在不完全是复制构造函数 - 它比复制构造函数更通用,因为它可以接受任何Tree接口实现并创建Nodes包含相同数据的新实例.