2

我有这门课,但我不明白到底发生了什么:

public class Table {
    private int[][] array;
    private int N;

    // constructor
    public Table(int[][] array) {
        N = array.length;
        this.array = Arrays.copyOf(array, N);
    }

    // this method returns another Table object
    public Table tweak() {
        int[][] tweak = Arrays.copyOf(array, N);
        // here I change the array
        return new Table(tweak);
    }
}

问题是当我调用调整方法时,用于调用该方法的对象也发生了变化:

public class TestCls {
    public static void main(String[] args) {
        int[][] array = {{1, 2}, 
                         {3, 4}};
        Table a = new Table(array);
        System.out.println(a.toString());
        /* this will print
        *  1  2 
        *  3  4
        */

        Table b = a.tweak();
        System.out.println(b.toString());
        /* this will print
        *  2  1 
        *  3  4
        */

        System.out.println(a.toString());
        /* this will also print
        *  2  1 
        *  3  4
        */
    }
}

请帮助我理解为什么会发生这种情况以及我应该如何更改调整方法以使原始对象不被更改。

谢谢

4

2 回答 2

11

Arrays.copyOf正在创建一个新的int[][],但这需要一个拷贝 - 它相当于:

int[][] tweak = new int[array.length][];
for (int i = 0; i < tweak.length; i++) {
    tweak[i] = array[i];
}

因此,虽然您有一个新的“顶级”数组,但每个“子数组”都是共享的。您真的想制作数组的深层副本:

int[][] tweak = new int[array.length][];
for (int i = 0; i < tweak.length; i++) {
    tweak[i] = array[i].clone(); // Simpler way of performing a shallow copy
}

这是对每个“子数组”执行浅拷贝,但这很好,因为元素类型只是int(没有办法让它“更深”)。

请注意,您只需要在方法构造函数中执行此操作。复制两份是没有意义的。tweak

于 2013-03-26T15:10:34.490 回答
5

问题是Table构造函数制作了数组的浅拷贝

请参阅如何在 Java 中进行二维数组的深拷贝?

于 2013-03-26T15:09:52.710 回答