2012-07-01 10 views
7

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

答えて

3

同じオブジェクトが同じ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つだけ持っているので、技術的にあなたがイコールとhashCodeメソッドをオーバーライドする必要はありません。

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

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

3

あなたは参照の等価のデフォルトObject.equals定義を使用して、あなたはまた、equalsをオーバーライドしないときは、hashCode()関数をオーバーライドする必要はありません唯一の時間です。これはあなたが望むものであってもなくてもかまいません。特に、同じフィールド値を持っていても異なるオブジェクトではなく、は等しいと見なされます。

あなたがequalsなくhashCodeをオーバーライドする場合は、HashMap動作は(読み:それは全く意味を成さず、完全に破壊されます)不定となります。

4

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

+2

彼が彼のために働くhashCodeを持つものを拡張していない限り、 – Miquel

2

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

だから、hashCode()の機能を持つクラスを拡張する場合を除き、自分で実装する必要があります。 equals()も実装してください:ArrayListのようなクラスはequalsのみを使用し、HashMapのようなクラスはhashCode()equals()の両方をチェックします。

+0

あなたは絶対に正しいです。ちょうどHashMap.put()を確認してください。本当に間違っていました。ありがとう!私はあなたのコメントを反映するために答えを修正しました。 – Miquel

+1

実装の詳細を確認することなく、抽象的なレベルでは、ハッシュの衝突を避けることができるため、抽象的なレベルでなければならないことがわかります。 'equals'が考慮されていなければ、ハッシュコードに衝突する2つのオブジェクトは同じになります。 –

0

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

0

Objectクラスのequals()およびhashCode()メソッドをオーバーライドする必要があります。 java.lang.Objectから継承されるequals()hashcode()のデフォルトの実装では、オブジェクトインスタンスのメモリ位置(例:[email protected])が使用されます。オブジェクトの2つのインスタンスが同じプロパティを持ちますが、継承されたequals()memory locationを使用するため、2つのインスタンスで異なるため、falseを返すと問題が発生する可能性があります。

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

主な考慮事項キー定義されたユーザーを実装する際に

  1. 、それはhashCode()をオーバーライドする必要があります。
  2. 2つのオブジェクトが等しい場合は、hashCodeの値も同じでなければなりません。
  3. フィールドがequals()で使用されていない場合は、hashCode()で使用しないでください。
  4. 頻繁にアクセスされる場合は、パフォーマンスを向上させるためのキャッシングの候補にはhashCode()があります。
関連する問題