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