How to deep copy an irregular 2D array

后端 未结 7 1784
情深已故
情深已故 2020-12-04 02:06

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

Ie.

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


        
相关标签:
7条回答
  • 2020-12-04 02:39

    Here's one that specializes to deeply cloning int[][]. It also allows any of the int[] to be 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!
        }
    }
    
    0 讨论(0)
  • 2020-12-04 02:43

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

    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

    0 讨论(0)
  • 2020-12-04 02:47

    N-dimensional deep copy

    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 讨论(0)
  • 2020-12-04 02:53

    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.

    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.

    0 讨论(0)
  • 2020-12-04 02:55

    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() :)

    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;
    }
    
    0 讨论(0)
  • 2020-12-04 02:57
    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().

    0 讨论(0)
提交回复
热议问题