java 如何深度复制不规则的二维数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/419858/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 12:18:56  来源:igfitidea点击:

How to deep copy an irregular 2D array

javaarraysdeep-copymultidimensional-array

提问by Sean McDaid

How can I deep copy an irregularly shaped 2D array in Java?

如何在 Java 中深度复制形状不规则的二维数组?

Ie.

IE。

int[][] nums =  {{5},
                 {9,4},
                 {1,7,8},
                 {8,3,2,10}}

I'm unable to use Arrays.arrayCopy()for some reason (versioning?)

Arrays.arrayCopy()由于某种原因我无法使用(版本控制?)

回答by Joao da Silva

int[][] copy = new int[nums.length][];

for (int i = 0; i < nums.length; i++) {
    copy[i] = new int[nums[i].length];

    for (int j = 0; j < nums[i].length; j++) {
        copy[i][j] = nums[i][j];
    }
}

You can replace the second loop with System.arraycopy() or Arrays.copyOf().

您可以用 System.arraycopy() 或 Arrays.copyOf() 替换第二个循环。

回答by slim

I wrote this in Eclipse, tested it, came back and found that Jo?o had beaten me to almost exactly the same solution. I upvoted him, but here's mine for comparison. I guess it's instructive to see the very slight details people choose to do differently.

我在 Eclipse 中写了这个,测试了它,回来发现 Jo?o 用几乎完全相同的解决方案击败了我。我赞成他,但这是我的比较。我想看到人们选择以不同方式做的非常细微的细节是有益的。

private static int[][] copy2d(int[][] nums) {
    int[][] copy = new int[nums.length][];

    for (int i = 0; i < copy.length; i++) {
        int[] member = new int[nums[i].length];
        System.arraycopy(nums[i], 0, member, 0, nums[i].length);
        copy[i] = member;
    }

    return copy;
}

For extra credit, try writing one that copies an n-dimensional array where n is arbitrary.

为了获得额外的积分,请尝试编写一个复制 n 维数组的程序,其中 n 是任意的。

回答by Chii

N-dimensional deep copy

N维深拷贝

public class ArrayTest extends TestCase {

    public void testArrays() {
        Object arr = new int[][]{
                {5},
                {9, 4},
                {1, 7, 8},
                {8, 3, 2, 10}
        };

        Object arrCopy = copyNd(arr);
        int height = Array.getLength(arr);
        for (int r = 0; r < height; r++) {
            Object rowOrigonal = Array.get(arr, r);
            Object rowCopy = Array.get(arrCopy, r);
            int width = Array.getLength(rowOrigonal);
            for (int c = 0; c < width; c++) {
                assertTrue(rowOrigonal.getClass().isArray());
                assertTrue(rowCopy.getClass().isArray());
                assertEquals(Array.get(rowOrigonal, c), Array.get(rowCopy, c));
                System.out.println(Array.get(rowOrigonal, c) + ":" + Array.get(rowCopy, c));
            }
        }
    }

    public static Object copyNd(Object arr) {
        if (arr.getClass().isArray()) {
            int innerArrayLength = Array.getLength(arr);
            Class component = arr.getClass().getComponentType();
            Object newInnerArray = Array.newInstance(component, innerArrayLength);
            //copy each elem of the array
            for (int i = 0; i < innerArrayLength; i++) {
                Object elem = copyNd(Array.get(arr, i));
                Array.set(newInnerArray, i, elem);
            }
            return newInnerArray;
        } else {
            return arr;//cant deep copy an opac object??
        }
    }
}

回答by David Moles

Some folks suggest clone()-- just to be extra clear, clone()on a multi-dimensional array is only a shallow clone. original.clone()[0] == original[0]. But (for primitives) you can use clone()instead of System.arraycopy()once you're down to one-dimensional arrays.

有些人建议clone()- 更清楚的是,clone()在多维数组上只是一个浅层克隆。original.clone()[0] == original[0]. 但是(对于原语)你可以使用clone()而不是System.arraycopy()一旦你下降到一维数组。

回答by JeanRe

Here is a simple convenient way to copy 2 dimensional arrays (compatible with DEEP copy) :

这是复制二维数组的一种简单方便的方法(与 DEEP 复制兼容):

public static char[][] cloneArray(char[][] array){
 char[][] copy = new char[array.length][];
 for(int i = 0 ; i < array.length ; i++){
  System.arraycopy(array[i], 0, copy[i] = new char[array[i].length], 0, array[i].length);
 }
 return copy;
}

plz note that you simple have to change array type to anything else, like int

请注意,您必须将数组类型更改为其他任何类型,例如 int

回答by polygenelubricants

Here's one that specializes to deeply cloning int[][]. It also allows any of the int[]to be null.

这是一个专门用于深度克隆的int[][]。它也允许任何int[]null

import java.util.*;

public class ArrayDeepCopy {

    static int[][] clone(int[][] arr) {
        final int L = arr.length;
        int[][] clone = new int[L][];
        for (int i = 0; i < clone.length; i++) {
            clone[i] = (arr[i] == null) ? null : arr[i].clone();
        }
        return clone;
    }

    public static void main(String[] args) {
        int[][] a = {
            { 1, },
            { 2, 3, },
            null,
        };
        int[][] b = a.clone();
        System.out.println(a[0] == b[0]); // "true", meaning shallow as expected!

        b = clone(a); // this is deep clone!
        System.out.println(Arrays.deepEquals(a, b)); // "true"
        System.out.println(a[0] == b[0]); // "false", no longer shallow!
    }
}

回答by Charles Miller

Another arbitrary n-d copy. It's ugly, and thanks to Java's type system you can't cast the result back to the array type you started with. Still, it works. Like the other comments say, use clone() :)

另一个任意的 nd 副本。这很丑陋,而且由于 Java 的类型系统,您无法将结果转换回您开始使用的数组类型。尽管如此,它仍然有效。就像其他评论说的那样,使用 clone() :)

public  void testMultiDimArray()
{
   int[][][] arr = new int[][][] {
           { {5}, {5, 6 }, {3, 3, 1} },
           { {1, 2, 3}, {4, 5 } }
   };

   Object[] dest = (Object[]) deepCopy(arr);
   // System.out.println(Arrays.deepToString(dest));
   assertTrue(Arrays.deepEquals(arr, dest));
}

public static Object deepCopy(Object src)
{
    int srcLength = Array.getLength(src);
    Class srcComponentType = src.getClass().getComponentType();

    Object dest = Array.newInstance(srcComponentType, srcLength);

    if (srcComponentType.isArray())
    {
        for (int i = 0; i < Array.getLength(src); i++)
            Array.set(dest, i, deepCopy(Array.get(src, i)));
    }
    else
    {
        System.arraycopy(src, 0, dest, 0, srcLength);
    }

    return dest;
}