Java:对于列表的深度复制,最佳方法是什么?

3

我正在努力编写一个过程来深度复制 List<List<Integer>>,我的做法如下:

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

这样做好吗?有没有可能摆脱内部循环?事实是,每个内部子列表都可以增长到很大的长度。

3
如果你想进行深拷贝,那么子列表的大小是无法避免的,某个时刻必须迭代它们(除非你可以构建一个写时复制机制)。 - Oliver Charlesworth
@shmosel:稍微调查一下也没什么坏处。看起来他们想要复制memcpy,而这在Java中的目的甚至不清楚。 - Makoto
@Makoto 在我的情况下,我需要有多个List<List<Integer>>,它们具有完全相同的值,但每个结构都有不同的哈希码。这样我就可以区分它们。我将在不同的地方多次调用上面的clone()过程。 - ramgorur
1
@Makoto - 我认为OP提到memcpy只是因为在C语言中,它通常比手动迭代和复制更快,而不是因为memcpy具有任何语义价值。他/她实际上是在问“我是否以尽可能高效的方式进行了深度复制?” - Oliver Charlesworth
1
使用复制构造函数确实可以让性能更接近于memcpy。请查看我的更新答案。 - shmosel
显示剩余8条评论
2个回答

8

这是一个好的做法吗?

可以。

能否去掉内部循环?

可以,你可以使用 ArrayList 的复制构造函数:

for( List<Integer> sublist : src) {
    dest.add(new ArrayList<>(sublist));
}

事实是,每个内部子列表都可以变得非常长。

上述代码将缩短代码,并委托给System.arraycopy,这可能会在一定程度上提高性能。它还避免了在填充空的ArrayList时重复调整大小/复制。但是,如果您确实需要深层复制,则基本上无法避免复制列表/数组的O(n)时间复杂度。由于您没有解释为什么需要深层复制,我只能相信您的话。


-2

你可以尝试使用一些并行的方法来加速程序,比如使用线程池来将工作分割成多个部分,在所有工作都完成后再将结果合并。

因为我现在在手机上,无法提供示例,但我会尽力寻找相关资料。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接