2009-01-07 55 views
4

如何在Java中深度複製不規則形狀的2D陣列?如何深度複製不規則的2D陣列

即,

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

我無法使用Arrays.arrayCopy()出於某種原因(版本?)

+1

沒有Arrays.arrayCopy()。有System.arrayCopy()(自Java 1.0以來就存在)和Arrays.copyOf()(自Java 6/Java 1.6以來就存在)。請澄清你的意思。 – 2009-01-07 10:44:32

+0

似乎是完全相同的 - 請參閱guerda的答案 – 2009-01-07 10:47:32

+0

@Paul:這不是重複的問題 - 你甚至讀過它嗎? – Draemon 2009-01-07 10:49:52

回答

12
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更換第二環()。

7

我在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是任意的。

3

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?? 
     } 
    } 
} 
0
另一個

任意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; 
} 
2

有些人建議clone() - 只是要格外清晰,clone()多維數組只是一個淺克隆。 original.clone()[0] == original[0]。但是(對於基元),一旦你使用一維數組,你可以使用clone()而不是System.arraycopy()

0

這裏是複製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

0

這裏的一個專門深入克隆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! 
    } 
}