3

次のように初期化されたハッシュマップがあります。

Hashmap<String[][], Boolean> tests = new Hashmap<String [][], Boolean>();

キーを初期化せずにテストに挿入したい:

tests.put({{"a"}, {"a"}}, true);

しかし、Javaは私にこれをさせていないようです。私がこのようにそれをするならば、それは働きます:

String[][] hi = {{"a"}, {"a"}};
tests.put(hi, true);

後者を回避して前者を機能させる方法はありますか?

誰かがこのエラーの背後にある理由を説明することもできますか?

ありがとう

4

4 に答える 4

4

はい、次のように書くことができます:

tests.put(new String[][] {{"a"}, {"a"}}, true);

これは、匿名配列またはジャストインタイム配列と呼ばれることがよくあります。

于 2012-07-21T17:48:54.423 に答える
4

あなたの場合、あなたは使用しなければならないでしょう

tests.put(new String[][]{{"a"}, {"a"}}, true);

お気づきのように{{"a"}, {"a"}}

String[][] hi = {{"a"}, {"a"}};

配列への参照を作成しているときにのみ使用できます。

于 2012-07-21T17:49:48.490 に答える
1

使用できます

tests.put(new String[][]{{"hello", "goodbye"},{"hi", "bye"}}, true);
于 2012-07-21T17:48:42.957 に答える
1

これはほぼ間違いなくあなたが望むものではありません。

Javaの配列は、それらの等価性とハッシュコードをObject-から取得します。つまり、参照IDに基づいています。それで:

String[] a = { "hello" }; // create one array
String[] b = { "hello" }; // create a different array with the same contents
assert a != b; // the two references are to different objects
assert ! a.equals(b); // they're not equal
assert a.hashCode() != b.hashCode(); // neither are their hashes (probably)

abは等しくなく、それらは異なるオブジェクトであるため、それらのハッシュコードはほぼ確実に等しくなりません。つまり、ハッシュマップのキーとして配列を使用する場合、キーを使用して値を取得することはできませんが、作成したものとまったく同じです。他の配列は異なるハッシュコードを持ち、等しくないため、同等のキーとは見なされません。

String[][]解決策は、をに置き換えることList<List<String>>です。リストは、その内容に基づいて等価性とハッシュコードを定義するため、を含むリスト[ "hello" ]は、以下を含む他のリストと同じです[ "hello" ]

List<String> x = Arrays.asList("hello");
List<String> y = Arrays.asList("hello");
assert x != y; // the two lists are different objects
assert x.equals(y); // but they're equal
assert x.hashCode() == y.hashCode(); // and so are their hash codes

これで、リストをキーとして使用できます。リストがマップのキーになると、値を変更することは許可されないことに注意してください。リストのハッシュコードが変更されているため、これを行うとハッシュマップが破損する可能性がありますが、マップはそれを認識しないため、マップは間違ったハッシュバケットでそれを検索します。

ここでの最も簡単なオプションは次のとおりです。

  1. 他の誰も同じListオブジェクトへの参照を持っておらず、それを変更する可能性があることを確認してください
  2. リストをマップに配置する前に、リストのディープコピーを作成します(つまり、「内側」のリストと「外側」のリストをコピーします)

2番目のオプションの場合、次のようになります。

// copy the outer list
List<List<String>> outerCopy = new ArrayList<List<String>>( originalList );
ListIterator<List<String>> listIterator = outerCopy.listIterator();
while (listIterator.hasNext()) {
    // make a copy of the inner list
    List<String> innerCopy = new ArrayList<String>( listIterator.next() );
    listIterator.set(innerCopy);
}
于 2012-07-21T19:35:41.637 に答える