1

Javaには、クラスがあります:

public static class Key {

    int[] vector = null;

    private int hashcode = 0;

    Key (int[] key) {
        vector = new int[key.length];
        // here is the problem
        System.arraycopy(key, 0, vector, 0, key.length);
    }

    public int hashCode() { ... }

    public boolean equals(Object o) { ... }

}

のキーとして機能しますHashMap<Key, int[]> map。コードで私は:

// value int[] array is filled before
map.put(new Key(new int[] {5, 7}), value);

ただし、これにより引数配列が{5, 7}2回作成されます.1回目Keyはコンストラクターが呼び出されたとき、次にそのコンストラクター内です。

何に使うのHashMap<int[], int[]> mapかわからないので使えません。そのため、キーをクラス内にラップします。hashCodeint[]int[]Key

引数配列 (サイズが異なる可能性があります) を一度だけ作成するにはどうすればよいですか?

私はこの解決策が好きではありません:

map.put(new Key(5, 7), value);

// and rewrite the constructor
Key (int a1, int a2) {
    vector = new int[2];
    vector[0] = a1;
    vector[1] = a2;
}

一般に、引数配列はさまざまなサイズになる可能性があるためです。

4

3 に答える 3

3

引数配列 (サイズが異なる可能性があります) を一度だけ作成するにはどうすればよいですか?

残念ながら、組み込みの Java 配列を不変にする方法がないため、これを行うことはできません。不変の配列を作成できる場合は、次のようにします。

Key (int[] key) {
    // Do not do this!!!
    vector = key;
}

上記は完全に協調的な環境では機能しますが、敵対的なユーザーが配列を渡し、キーにハッシュを計算させ、配列要素を変更してコードにエラーを導入する可能性があります。そのため、渡された配列をコピーすることにしたとき、あなたは絶対に正しいです。

次のように、可変数の引数を受け入れるように関数を変更できます。

Key (int ... key) {
    vector = new int[key.length];
    System.arraycopy(key, 0, vector, 0, key.length);
}

これにより、明示的にではなく暗黙的に配列を作成できます。

map.put(new Key(5, 7), value);
于 2013-03-18T01:24:21.537 に答える
1

パラメータにvarargsを使用し、次を使用しArrays.copyOf()ます。

Key (int... key) {
    vector = Arrays.copyOf(key, key.length);
}

int パラメーター (パラメーターなしを含む) の場合は任意の数でコンストラクターを呼び出すことができ、エラーは発生しません。

于 2013-03-18T01:23:51.353 に答える
1

arraycopyはあるオブジェクトから別のオブジェクトへのディープ コピーを行うために使用されているため、ある時点で、2 番目のオブジェクトが引数配列と同じサイズである 2 つのオブジェクトを作成する必要があります。だからvector = new int[key.length];正しいように見えます。

ところで、コードをコンパイルすると、クラスの有効な修飾子ではないというエラーが表示さstaticれます。publicabstractfinal

于 2013-03-18T01:28:46.590 に答える