8

簡単な質問:HashMapカスタムクラスをキーとして使用する場合、関数をオーバーライドする必要がありますか?hashCodeその関数をオーバーライドしない場合、どのように機能しますか?

4

6 に答える 6

5

hashCode AND equalsをオーバーライドしない場合、内容に関係なく、各オブジェクトが異なるというデフォルトの動作が得られます。

于 2012-07-01T10:21:15.387 に答える
4

hashCode()関数をオーバーライドする必要がないのは、オーバーライドしない場合だけなので、参照の等式equalsのデフォルトの定義を使用します。Object.equalsこれは、希望するものである場合とそうでない場合があります。特に、フィールド値が同じであっても、異なるオブジェクトは等しいとは見なされません。

オーバーライドしても動作が定義されequalsていない場合(読み取り:まったく意味がなく、完全に破損します)hashCodeHashMap

于 2012-07-01T10:20:29.273 に答える
4

技術的には、等しいオブジェクトが同じhashCodeを持っている限り、hashCodeメソッドをオーバーライドする必要はありません。

したがって、Objectで定義されたデフォルトの動作を使用する場合、equalsは同じインスタンスに対してのみtrueを返しますが、hashCodeメソッドをオーバーライドする必要はありません。

ただし、equalsメソッドとhashCodeメソッドをオーバーライドしない場合は、常に同じキーインスタンスを使用していることを確認する必要があります。

例えば:

MyKey key1_1 = new MyKey("key1");

myMap.put(key1_1,someValue); // OK

someValue = myMap.get(key1_1); // returns the correct value, since the same key instance has been used;

MyKey key1_2  = new MaKey("key1"); // different key instance

someValue = myMap.get(key1_2); // returns null, because key1_2 has a different hashCode than key1_1 and key1_1.equals(key1_2) == false

実際には、キーのインスタンスが1つしかないことが多いため、技術的には、equalsメソッドとhashCodeメソッドをオーバーライドする必要はありません。

ただし、キーとして使用されるクラスのequalsメソッドとhashCodeメソッドをオーバーライドすることをお勧めします。これは、後であなたや別の開発者が同じインスタンスを使用する必要があることを忘れてしまい、問題の追跡が困難になる可能性があるためです。

注:equalsメソッドとhashCodeメソッドをオーバーライドする場合でも、equalsメソッドまたはhashCodeメソッドの結果を変更するような方法でキーオブジェクトを変更しないようにする必要があります。そうしないと、マップで値が見つかりません。もう。そのため、可能であれば不変オブジェクトをキーとして使用することをお勧めします。

于 2012-07-01T11:41:49.800 に答える
3

キーとして使用しているオブジェクトクラスによって異なります。あなたが提案するようなカスタムクラスであり、何も拡張しない(つまり拡張するObject)場合、hashCode関数はの関数になり、Objectメモリ参照を考慮して、同じように見える2つのオブジェクトを異なるコードにハッシュします。

そうhashCode()です、あなたがあなたのために働くことがわかっている関数でクラスを拡張しているのでない限り、あなたはあなた自身のものを実装する必要があります。また、必ず実装してequals()ください。のような一部のクラスArrayListはequalsのみを使用しますが、HashMapのような他のクラスはとの両方をチェックしhashCode()ますequals()

于 2012-07-01T10:21:37.017 に答える
0

キーが不変でない場合は、問題が発生する可能性があることも考慮してください。変更可能なキーを含むエントリをマップに配置し、後でハッシュコードに影響を与えるようにキーを変更すると、マップ内のエントリが失われる可能性があります。これは、それを取得できなくなるためです。

于 2012-07-01T11:28:01.803 に答える
0

Objectクラスのメソッドequals()とメソッドをオーバーライドする必要があります。から継承されるおよびhashCode()のデフォルトの実装は、オブジェクトインスタンスのメモリ位置を使用します(例)。これは、オブジェクトの2つのインスタンスが同じプロパティを持っているが、2つのインスタンスで異なるを使用するため、継承されたものが返される場合に問題を引き起こす可能性があります。equals()hashcode()java.lang.ObjectMyObject@6c60f2eaequals()falsememory location

また、toString()メソッドをオーバーライドして、オブジェクトの適切な文字列表現を提供することもできます。

ユーザー定義キーを実装する際の主な考慮事項

  1. クラスがをオーバーライドする場合は、をオーバーライドequals()する必要がありますhashCode()
  2. 2つのオブジェクトが等しい場合、それらのhashCode値も等しくなければなりません。
  3. フィールドがで使用されていない場合は、で使用しequals()てはなりませんhashCode()
  4. 頻繁にアクセスされる場合hashCode()は、パフォーマンスを向上させるためのキャッシュの候補です。
于 2013-04-07T09:05:24.130 に答える