假设我有以下代码:
public class Collection implements CollectionInterface{
ElementInterface[] elementArray = new ElementInterface[100];
int amountOfElements = 0;
public Collection()
{
}
public Collection(CollectionInterface collection)
{
CollectionInterface tempCollection = new Collection();
while(!collection.isEmpty())
{
ElementInterface element = collection.Remove().clone();
tempCollection.Add(element.clone2());
elementArray[amountOfElements++] = element;
}
collection = tempCollection;
}
public void Add(ElementInterface element){
elementArray[amountOfElements++] = element;
}
public ElementInterface Remove(){
ElementInterface element = elementArray[amountOfElements].clone2();
elementArray[amountOfElements] = null;
amountOfElements--;
return element;
}
public boolean isEmpty(){
return amountOfElements == 0;
}
public CollectionInterface clone()
{
return new Collection(this);
}
}
好吧,它看起来有点奇怪,而且确实如此。但是,如果我使用以下代码:
CollectionInterface collection = new Collection();
collection.Add(new Element("Foo"));
collection.Add(new Element("Bar"));
CollectionInterface collection2 = collection.clone();
第一个不再包含任何元素。怎么可能?
答案 0 :(得分:2)
这很有道理。在构造函数中,clone()
以原始集合作为参数调用,使用:
ElementInterface element = collection.Remove().clone();
因此,您在创建新元素时从原始集合中删除元素。你不想这样做......
鉴于您的CollectionInterface
仅具有Add
和Remove
方法,应该达到您想要的效果并不是很清楚是add
和remove
遵循Java命名约定来处理元素 - 无法以非破坏性方式访问集合。对于集合类型,非常奇数。您是否有任何理由首先这样做而不是使用内置集合?
Remove
(就像你现在一样)但是当你构建了数组时,可以使用:
for (int i = 0; i < amountOfElements; i++)
{
collection.Add(elementArray[i].clone2());
}
......这将使元素重新回归。这是可怕的虽然......
答案 1 :(得分:1)
在第二个构造函数中尝试时,无法更改输入参数的引用。
collection = tempCollection.
a)这是一个语法错误,
b)collection
是一个局部变量;分配给它将不会改变构造函数的外部。
答案 2 :(得分:1)
您可以按如下方式实现Clone方法:
public Object Clone() {
Collection rv = new Collection();
for (ElementInterface element : elementArray) {
rv.Add(element.clone());
}
return rv;
}
如果需要,您可以在构造函数中轻松实现它。