如何在Java中深度複製不規則形狀的2D陣列?如何深度複製不規則的2D陣列
即,
int[][] nums = {{5},
{9,4},
{1,7,8},
{8,3,2,10}}
我無法使用Arrays.arrayCopy()
出於某種原因(版本?)
如何在Java中深度複製不規則形狀的2D陣列?如何深度複製不規則的2D陣列
即,
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??
}
}
}
任意N d副本。這很醜陋,並且由於Java的類型系統,您不能將結果轉換回開始的數組類型。它仍然有效。像其他評論說,利用克隆():)
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;
}
有些人建議clone()
- 只是要格外清晰,clone()
多維數組只是一個淺克隆。 original.clone()[0] == original[0]
。但是(對於基元),一旦你使用一維數組,你可以使用clone()
而不是System.arraycopy()
。
這裏是複製2個維數組(與深拷貝兼容)的簡單方便的方法:
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請注意,您簡單得改變數組類型爲別的,如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!
}
}
沒有Arrays.arrayCopy()。有System.arrayCopy()(自Java 1.0以來就存在)和Arrays.copyOf()(自Java 6/Java 1.6以來就存在)。請澄清你的意思。 – 2009-01-07 10:44:32
似乎是完全相同的 - 請參閱guerda的答案 – 2009-01-07 10:47:32
@Paul:這不是重複的問題 - 你甚至讀過它嗎? – Draemon 2009-01-07 10:49:52