有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java中的通用LinkedList克隆

我想克隆任何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) 个答案

  1. # 1 楼答案

    正如评论中提到的,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的

  2. # 2 楼答案

    由于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;
    }