Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java:实现列表深度复制的最佳方法_Java_List_Arraylist_Clone_Deep Copy - Fatal编程技术网

java:实现列表深度复制的最佳方法

java:实现列表深度复制的最佳方法,java,list,arraylist,clone,deep-copy,Java,List,Arraylist,Clone,Deep Copy,我正在尝试编写一个程序来执行列表的深度复制,我是这样做的: public static List<List<Integer>> clone(final List<List<Integer>> src) { List<List<Integer>> dest = new ArrayList<List<Integer>>(); for( List<Integer> sublist

我正在尝试编写一个程序来执行
列表的深度复制,我是这样做的:

public static List<List<Integer>> clone(final List<List<Integer>> src)
{
    List<List<Integer>> dest = new ArrayList<List<Integer>>();
    for( List<Integer> sublist : src) {
        List<Integer> temp = new ArrayList<Integer>();
        for(Integer val: sublist) {
            temp.add(val);
        }
        dest.add(temp);
    }
    return dest ;
} 
公共静态列表克隆(最终列表src)
{
List dest=new ArrayList();
对于(列表子列表:src){
List temp=new ArrayList();
for(整型值:子列表){
温度添加(val);
}
目的地添加(温度);
}
返回目的地;
} 
这是一个好方法吗?有可能去掉内部循环吗?事实上,每个内部子列表都可以增长到很长的长度

这是一个好方法吗

很好

有可能去掉内部循环吗

是的,您可以使用
ArrayList
copy构造函数:

for( List<Integer> sublist : src) {
    dest.add(new ArrayList<>(sublist));
}
for(列表子列表:src){
目的添加(新数组列表(子列表));
}
事实上,每个内部子列表都可以增长到很长的长度

上述操作将缩短代码,并将其委托给
System.arraycopy
,这很可能会。它还可以避免在填充空的
ArrayList
时重复调整大小/复制。但是,如果您确实需要深度复制,那么根本无法避免复制列表/数组的O(n)时间复杂性。既然你没有解释你为什么需要一份深度副本,我就不得不相信你的话。

试试这个

public static <T> List<List<T>> clone(final List<List<T>> src) {
    return src.stream()
        .map(list -> list.stream().collect(Collectors.toList()))
        .collect(Collectors.toList());
} 
公共静态列表克隆(最终列表src){
返回src.stream()
.map(list->list.stream().collect(Collectors.toList()))
.collect(Collectors.toList());
} 

您可以使用一些并行方法来加快速度,比如首先使用线程池来拆分工作,然后在完成所有工作后将结果合并在一起


我不能提供一个例子,因为我在手机上,但可能会尝试这样做。

如果你想做一个深度复制,那么你对子列表的大小无能为力-在某个时候需要对它们进行迭代(除非你能建立一个写时复制机制)。
Integer
是不可变的;对
整数所做的任何操作都将丢失,除非将其重新添加到列表中的正确位置。你为什么认为你想要一份深度拷贝?这是离题的。试试codereview.stackexchange.com。@Makoto-我相信OP指的是
memcpy
,只是因为在C语言中它通常比手动迭代和复制快,而不是因为
memcpy
有任何语义值。他/她本质上是在问“我是否在尽可能高效地进行深度复制?”。使用复制构造函数确实会使您的性能更接近
memcpy
。查看我的更新答案。我为什么要尝试此选项?效率更高吗?请解释。除非您正在重写
对象#clone
@ramgorur,否则不要命名方法
clone
。@ramgorur如果不进行测试,很难说它的效率是高还是低,但它确实摆脱了内部循环(以及外部循环)。但是如果您计划修改返回值,
Collectors.toList()
不承诺返回可变结果。您必须使用
Collectors.toCollection(ArrayList::new)