如何深度复制不规则的2D数组

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

IE浏览器。

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

我出于某种原因无法使用Arrays.arrayCopy() (版本化?)

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

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

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

要获得额外的功劳,请尝试编写一个复制n维数组的数据,其中n是任意的。

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

有些人建议clone() – 只是为了更清楚,多维数组上的clone()只是一个浅层克隆。 original.clone()[0] == original[0] 。 但是(对于基元),一旦进入一维数组,就可以使用clone()而不是System.arraycopy()

另一个任意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; } 

这是复制2维数组的简单方便方法(与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; } 

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

这是一个专门深入克隆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! } }