web-dev-qa-db-ja.com

配列のゲッターとセッター

配列のゲッターとセッターについていくつか質問があります。次のようなクラスがあり、そのコンストラクターで配列のプライベートコピーを作成するとします。

import Java.util.Arrays;

public class Foo
{
    private int[] array;

    public Foo(int[] array) {
        this.array = Arrays.copyOf(array, array.length);
    }
}

ゲッターとセッターを介してのみ配列にアクセス/変更する必要があります。次のようなゲッターがある場合:

public int[] getArray() {
    return array;
}

ユーザーが配列の要素を直接変更できるようにする参照を返すため、ゲッターの目的に反します。例えば.

Foo foo = new Foo(someArray);
...
int[] bar = foo.getArray();
bar[0] = 123; // Now foo.array[0] = 123 and we haven't used a setter!

したがって、おそらく次のようなものが必要です。

public int getElement(int index) {
    return array[index];
}

セッターについても同様です。しかし、要素ごとに処理を行う場合は、長さを取得する手段も提供する必要があります。

public int getArrayLength() {
    return array.length;
}

これは1次元配列では既に少し厄介ですが、代わりに多次元配列があるとします。

import Java.util.Arrays;

public class Foo
{
    private int[][][] array;

    public Foo(int[][][] array) {
        // Code for making a deep copy here
    }

    public int getElement(int i, int j, int k) {
        return array[i][j][k];
    }

    public void setElement(int i, int j, int k, int value) {
        array[i][j][k] = value;
    }

    public int getArrayLength() {
        return array.length;
    }

    public int getArrayLength(int i) {
        return array[i].length;
    }

    public int getArrayLength(int i, int j) {
        return array[i][j].length;
    }
}

これはそのような些細なタスクのための多くのコードであり、さらに重要なことに、実際に使用するのは面倒です。私たちは本当にこのようなものに終わる必要がありますか、それを行うより良い方法はありますか?私はあちこち見回しましたが、これに対する「標準的な慣習」はないようです。

11
user837324

多次元配列も1次元配列です:int[a][b][c]は本当にint[a*b*c]、つまり問題は結局のところ、どのようにして安全にアクセスを提供できますか?単にこのように:

public class Foo {
    private int[] array;

    public Foo(int[] array) {
        this.array = Arrays.copyOf(array, array.length);
    }

    /** @return a copy of the array */
    public int[] getArray() {
        return Arrays.copyOf(array, array.length);
    }
}

それでおしまい。

呼び出し元は配列の安全なコピーを持っており、配列が使用される通常の方法でそれを使用できます。委任メソッドは必要ありません。

8
Bohemian

ArrayListは何をしていると思いますか、またはその前にVectorと思いますか?

この時点で、Fooが配列に裏付けられていることを明らかにしているのはなぜでしょうか。カプセル化しようとしている場合は、あちこちにアクセサとセッターを配置する必要はありません。配列のクラスラッパーを作成しようとしているだけの場合は、インターフェイスを用意し、IntListか何かに名前を付け、Fooを具体的な実装にして、リスト。

1
Mark Peters

最初の部分に関して、ゲッターはコンストラクターのように見えない可能性がありますか?

public int[] getArray() {
    return Arrays.copyOf(array, array.length);
}
1
luketorjussen

多次元汎用配列用の小さなAPIを書きました。ディメンションが何であれ、各要素のゲッター、セッターがあります。

github上のMDDAJ

次に例を示します。5次元の文字列配列を作成します。

MDDAPseudo<String> c = new MDDAPseudo<String>(10,20,5,8,15);
c.set("xyz", 0,0,2,1,0); // setter indices: [0][0][2][1][0]
String s = c.get(0,0,0,0,0); // getter indices [0][0][0][0][0]

ボヘミアンはあなたが1つの次元しか使用できないとすでに書いています。この場合、クラスPDDAPSeudo internalも1つの次元を持ちます。しかし、APIは多次元配列のようなアクセスを提供します

0
timaschew