Java中的通用LinkedList克隆

时间:2016-01-23 11:11:33

标签: java generics

我想克隆任何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;
    }

2 个答案:

答案 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;
}