3

Vを、Kという名前の単一の属性とそのゲッターおよびセッターを持つクラスとします。

私がした場合に何が起こるはずです:

V v = new V();
v.setK("a");
HashMap<K,V> map = new HashMap<K,V>();
map.put(v.getk(),v);
v.setK("b");

私の知る限り、マップキーは不変であると想定されているため、これはある種の問題を引き起こすはずです。ここで何が起こりますか?

編集:以下のコメントで述べられているように、キーは文字列ではなく可変オブジェクトであると考えてください。

4

5 に答える 5

6

「マップ」インターフェースJavaDocからの引用:

可変オブジェクトをマップキーとして使用する場合は、細心の注意を払う必要があります。オブジェクトがマップのキーであるときに、等しい比較に影響を与える方法でオブジェクトの値が変更された場合、マップの動作は指定されません。

キーを変更しないでください(「hashCode」/「equals」を変更する方法で)。試してみると、間違いなく非常に長くてひどいデバッグになります。

図書館で本を交換するようなものです。インデックスの信頼性が低下しました。「Bradbury」を検索しますが、「Simak」が見つかります。

于 2012-04-14T12:15:59.313 に答える
2

vでゲッターによって返される値を変更したため、それを使用してマップを検索しようとしてもv.getk()、エントリは見つかりませんでした。

つまり、マップはvオブジェクトに何が起こるかと魔法のように同期しているわけではなく、で指定された値を使用します(そして使用し続けます)put()

于 2012-04-14T11:01:19.063 に答える
2
V v = new V();
v.setK("a");
HashMap<K,V> map = new HashMap<K,V>();
map.put(v.getk(),v);

//Nothing will change in the hashmap with this step
v.setK("b");

しかし、問題はマップからオブジェクトVをフェッチしているときに発生します。map.get(v.getk())を呼び出すと、マップ内の値がオブジェクト「a」にマップされているため、nullになります。ただし、この文字列 "a"はinterであるため、map.get("a");またはによってマップからこのオブジェクトをいつでもフェッチできます。

V v = new V();
v.setK("a");
map.get(v.getK());

PS:私はこれを実行しようとしませんでした

于 2012-04-14T11:10:09.800 に答える
1

v.setK()を呼び出すことにより、HashMapのキーを変更することはありません。したがって、Vオブジェクトに間違った情報が含まれているだけです。

于 2012-04-14T11:01:23.367 に答える
1

この質問のタイトルは誤解を招く可能性があります。マップキーとして使用されるオブジェクトを変更する場合のように、マップキーを変更することはありません。と言うと、キーの2つの独立した値を集約するマップエントリmap.put(x, y)を作成します。キーの発信元がマップに表示されていない場合、それは2つのオブジェクトにすぎません。したがって、マップエントリを作成し、その後vの状態を変更しただけです。これがマップエントリのキー「a」に影響を与える可能性はありません。一方、自分で作成したオブジェクトKがある場合は、次のようになります。("a", v)

public class K { 
  private String s;
  public K(String s) { this.s = s; }
  public void setS(String s) { this.s = s; }
  public boolean equals(Object o) { return ((K)o).s.equals(this.s); }
  public int hashCode() { return s.hashCode(); }

}

そして今、あなたはします

final K k = new K("a");
map.put(k, v);
k.setS("b");
map.get(k);

次に、問題に直面します。マップキーとして使用されるオブジェクトを変更しました

于 2012-04-14T11:05:46.710 に答える