Why does Array.copyOf() mutate the original array in case of 2D Arrays?

后端 未结 2 1222
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-23 13:39

If I create a 2D int array in Java, and then make a copy of it using Arrays.copyOf(), like so -

jshell> int[][] c1 = {{1,2}, {3,4}}
c         


        
2条回答
  •  迷失自我
    2021-01-23 14:02

    Method Arrays.copyOf does not perform a deep copy of an array, nor does System.arraycopy method. You should implement the algorithm of deep copy of the array yourself with the required copy depth. For example:

    int[][] arr1 = {{1, 2}, {3, 4}};                 // original array
    int[][] arr2 = Arrays.copyOf(arr1, arr1.length); // shallow copy
    int[][] arr3 = Arrays.stream(arr1)               // deep copy
            .map(Arrays::stream)
            .map(IntStream::toArray)
            .toArray(int[][]::new);
    
    arr1[0][0] = 7;
    
    System.out.println(Arrays.deepToString(arr1)); // [[7, 2], [3, 4]]
    System.out.println(Arrays.deepToString(arr2)); // [[7, 2], [3, 4]]
    System.out.println(Arrays.deepToString(arr3)); // [[1, 2], [3, 4]]
    

    And the same is true for an array of objects:

    public class Test {
        public static void main(String[] args) {
            SomeObject[] arr1 = {                                 // original array
                    new SomeObject(1),
                    new SomeObject(2),
                    new SomeObject(3),
                    new SomeObject(4)};
            SomeObject[] arr2 = Arrays.copyOf(arr1, arr1.length); // shallow copy
            SomeObject[] arr3 = Arrays.stream(arr1)               // deep copy
                    .mapToInt(SomeObject::getField)
                    .mapToObj(SomeObject::new)
                    .toArray(SomeObject[]::new);
    
            arr1[0].setField(7);
    
            System.out.println(Arrays.toString(arr1)); // [7, 2, 3, 4]
            System.out.println(Arrays.toString(arr2)); // [7, 2, 3, 4]
            System.out.println(Arrays.toString(arr3)); // [1, 2, 3, 4]
        }
    
        static class SomeObject {
            int field;
    
            public SomeObject(int field) { this.field = field; }
    
            public int getField() { return field; }
    
            public void setField(int field) { this.field = field; }
    
            public String toString() { return String.valueOf(field); }
        }
    }
    

提交回复
热议问题