Search code examples
javaarraysgenericsclone

Java generic array deep copy and cloning generic object


I would like to do a deep copy of a primitive array of n dimensions.

public static double[] deepCopy(double[] arr) {
    return arr.clone();
}

public static double[][] deepCopy(double[][] arr) {
    arr = arr.clone();
    for (int i = 0; i < arr.length; i++) {
        arr[i] = deepCopy(arr[i]);
    }
    return arr;
}

public static double[][][] deepCopy(double[][][] arr) {
    arr = arr.clone();
    for (int i = 0; i < arr.length; i++) {
        arr[i] = deepCopy(arr[i]);
    }
    return arr;
}

Above is the code to deep copy a double array of 1, 2, and 3 dimensions. I would like to generalize for any primitive type and/or generalize for the dimension of the array. I would like both, but I know a lot of things in Java are not possible, so it is okay if you can only get one, or tell me why it wouldn't work.

Thank you!


Solution

  • To deep copy a multi-dimensional array, use the following code.

    Note that this is only a deep copy of array values, not of any non-array values in the array, so the copy is only truly deep for multi-dimensional primitive arrays. It is deep-shallow for multi-dimensional object arrays.

    The declared type of the array doesn't matter. E.g. an Object[][] can contain array-objects, making it (partially) a 3D array. Those 3rd dimension arrays are copied too.

    The method will copy 1-dimensional object arrays, but not 1-dimensional primitive arrays. To copy 1-dimensional primitive arrays, use clone().

    @SuppressWarnings("unchecked")
    public static <T> T[] deepCopyArray(T[] array) {
        return (T[]) deepCopyArrayInternal(array);
    }
    private static Object deepCopyArrayInternal(Object array) {
        int length = Array.getLength(array);
        Object copy = Array.newInstance(array.getClass().getComponentType(), length);
        for (int i = 0; i < length; i++) {
            Object value = Array.get(array, i);
            if (value != null && value.getClass().isArray())
                value = deepCopyArrayInternal(value);
            Array.set(copy, i, value);
        }
        return copy;
    }