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);
    }
}

問題は、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
        */
    }
}

これが発生する理由と、元のオブジェクトが変更されないようにtweakメソッドを変更する方法を理解するのを手伝ってください。

ありがとう

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(「より深く」する方法はありません)、問題ありません。

これは、メソッドまたはコンストラクターのいずれかでのみ必要であることに注意してください。2つのコピーを作成しても意味がありません。tweak

于 2013-03-26T15:10:34.490 に答える
5

問題は、Tableコンストラクターが配列の浅いコピーを作成することです。

Javaで2D配列のディープコピーを作成するにはどうすればよいですか?を参照してください。

于 2013-03-26T15:09:52.710 に答える