我想克隆任何LinkedList,无论它是否包含可以是原始包装器的东西。我知道它可以是一个深度递归调用来获得真正的深度克隆 - 但我只需要一个级别的克隆。我无法编译以下代码:
<T> LinkedList<T> deepCloneOneLevel (final LinkedList<T> input){
if(input != null){
LinkedList<T> clone = new LinkedList<>();
for (T t: input){
clone.add(t.clone()); //error : clone() has protected access
}
return clone;
}
return null;
}
答案 0 :(得分:2)
正如评论中所提到的,Java的Cloneable不是克隆对象的非常友好的方法。因此,您可能需要定义Cloneable
接口,并确保
interface MyClone<T>{
T clone();
}
在你的代码中使用它
<T extends MyClone<? super T>> LinkedList<T> deepCloneOneLevel (final LinkedList<T> input){
if(input != null){
LinkedList<T> clone = new LinkedList<>();
for (T t: input){
clone.add(t.clone());
}
return clone;
}
return null;
}
MyClone
的实现知道浅拷贝是否足够或需要深拷贝
但是如果类型没有实现MyClone
怎么办?好问题。我们可以添加一个需要clone
“工厂”的重载。
<T> LinkedList<T> deepCloneOneLevel (final LinkedList<T> input, Function<T,T> factory){
if(input != null){
LinkedList<T> clone = new LinkedList<>();
for (T t: input){
clone.add(factory.apply(t));
}
return clone;
}
return null;
}
如果您的平台还没有Function
,您可以轻松编写自己的平台,或使用Guava的平台。
答案 1 :(得分:1)
由于clone()
方法在java世界中是一个很大的混乱,一个解决方案可能是使用apache commons SerializationUtils。它使用序列化来复制对象,因此速度很慢。更糟糕的是,如果您的类包含不支持序列化的字段,您将遇到麻烦。这是一个例子:
<T extends Serializable> LinkedList<T> deepCloneOneLevel (final LinkedList<T> input) {
if (input != null) {
LinkedList<T> clone = new LinkedList<>();
for (T t : input){
clone.add(SerializationUtils.clone(t));
}
return clone;
}
return null;
}