2

これはかなり長い間私を悩ませてきました。基本的に、独自のオブジェクト セット (ここでは MyObject と呼びます) をキーとしてマップに格納する場合、クラスのどこかに正確に同じオブジェクトが保存されていない限り、キー値を取得できません。同じ値を持つ 2 つのオブジェクトを比較すると通常 true を返す MyObject の equals メソッドをオーバーライドしようとしても、何も変わりませんでした。

私が言いたいことのデモンストレーションをあなたに与えるために:


Map<Integer, Integer> map = new HashMap<Integer, Integer>();
map.put(2, 3);
System.out.println(map.get(2)));

ここで、ご想像のとおり、マップで整数オブジェクト 2 を検索し、3 を出力します。整数が存在しない場合は、null を出力します。ここまでは順調ですね。


Map<String, Integer> map = new HashMap<String, Integer>();
map.put(new String("hi"), 3);
System.out.println(map.get(new String("hi")));

これも期待どおりに動作します。キー「hi」の値を取得しているだけです。


Map<MyObject, Integer> map = new HashMap<MyObject, Integer>();
map.put(new MyObject(), 3);
System.out.println(map.get(new MyObject()));

「new MyObject()」と「new MyObject()」の間に技術的な違いはありませんが、新しい MyObject をクラスのインスタンスとして保存し、そのインスタンスをパラメーターとして使用しない限り、とにかく null を返します。 get メソッド。

私の MyObject とは対照的に、キーが文字列または整数の場合、マップはキー値を簡単に取得しました。これらのタイプは特権を持っているだけですか、それともマップに「ねえ、新しく作成されたオブジェクトはそのリストのオブジェクトと似ています」と伝える方法はありますか? マップはオブジェクトをどのように比較しますか?

4

7 に答える 7

3

ハッシュが有効なデータ構造 ( HashMap、 などHashSet) が正しく機能するには、メソッドに加えてその要素またはキーをオーバーライドする必要があります。 その理由は、要素またはキーを入れるバケット (挿入中) または検索 (ルックアップ中に使用) を識別するためにハッシュ コードが使用されるためです。hashCode()equals()equals()

をオーバーライドしない場合hashCode()、 からのデフォルトの実装Object#hashCode()が使用され、同等と見なされるオブジェクトに対しても異なる値が返されます (equals()メソッドはtrueを返します)。

これがあなたの理由です

 may.get(myObject)

myObjectすでに存在しているにもかかわらず、呼び出しが失敗しています。ハッシュ コードが一致しHashMapないため、正しいバケット内のキーを検索することはありません。したがって、equals()ここで呼び出されることはありません。

于 2013-10-02T23:39:47.083 に答える