この質問にはすでに答えがあります。
オーバーライドしながら言っていろいろな所で読みましたequals
Javaのメソッド、オーバーライドする必要がありますhashCode
メソッドも、そうでなければそれは "契約違反"です。
しかし、これまでのところ、equalsメソッドのみをオーバーライドし、hashCodeメソッドをオーバーライドしないのであれば、問題は発生していません。
契約とは何ですか?契約に違反しても、なぜ問題にならないのですか。 hashCodeメソッドをオーバーライドしていないと、どのような場合に問題が発生しますか?
あなたが持つ問題は、要素の統一性が両方に従って計算されるコレクションにあります.equals()
そして.hashCode()
例えば、HashMap
。
その名前が暗示するように、それはハッシュテーブルに頼ります、そして、ハッシュバケツはオブジェクトの機能です.hashCode()
。
2つのオブジェクトがある場合.equals()
、しかし、異なるハッシュコードを持っている、あなたは失う!
ここで重要な契約の部分は次のとおりです。あるオブジェクト.equals()
同じ持っている必要があります.hashCode()
。
これはすべてに文書化されていますのJavadocObject
。そしてジョシュアブロッホあなたはそれをしなければならないと言う効果的なJava。十分に言った。
==
) - fge
ドキュメントによると、hashCodeのデフォルト実装はオブジェクトごとに異なる整数を返します。
合理的に実用的である限り、クラスObjectによって定義されたhashCodeメソッドは、 異なるオブジェクトに対して異なる整数を返します。 (これは典型的には オブジェクトの内部アドレスを整数に変換しますが、この実装は
JavaTMプログラミング言語ではこの手法は必要ありません。)
ただし、同じ意味を持つ異なるオブジェクトに対してハッシュコードを同じにしたい場合があります。例えば
Student s1 = new Student("John", 18);
Student s2 = new Student("John", 18);
s1.hashCode() != s2.hashCode(); // With the default implementation of hashCode
HashTable、HashSetなどのコレクションフレームワークでハッシュデータ構造を使用すると、この種の問題が発生します。特にHashSetのようなコレクションでは、要素が重複してSet規約に違反することになります。
はい、上書きされるべきです。上書きする必要があると思う場合equals()
その後、あなたが上書きする必要がありますhashCode()
およびその逆。の一般契約ハッシュコード()です:
Javaアプリケーションの実行中に同じオブジェクトに対して複数回呼び出される場合は、オブジェクトの等価比較で使用される情報が変更されていない限り、hashCodeメソッドは常に同じ整数を返す必要があります。この整数は、アプリケーションの実行ごとに同じアプリケーションの実行ごとに一貫性を保つ必要はありません。
2つのオブジェクトがequals(Object)メソッドに従って等しい場合、2つのオブジェクトのそれぞれでhashCodeメソッドを呼び出すと、同じ整数結果が得られます。
2つのオブジェクトがequals(java.lang.Object)メソッドに従って等しくない場合、2つの各オブジェクトでhashCodeメソッドを呼び出すと、異なる整数結果が得られる必要はありません。ただし、プログラマは、等しくないオブジェクトに対して個別の整数結果を生成すると、ハッシュテーブルのパフォーマンスが向上する可能性があることに注意する必要があります。
にhashCode()
それは言います:
2つのオブジェクトが
equals(Object)
方法、 それからhashCode
2つのオブジェクトそれぞれのメソッドしなければならない 同じ整数結果を生成する。
(私が強調する)
上書きするだけの場合equals()
ではなくhashCode()
あなたのクラスはこの契約に違反しています。
これは、のJavaDocでも言われています。equals()
方法:
通常は上書きする必要があります。
hashCode
方法 一般を維持するために、このメソッドがオーバーライドされるたびに の契約hashCode
メソッド。等しいオブジェクトは必ず ハッシュコードが等しい
契約は、2つのオブジェクトが等しい場合は同じハッシュコードを持つべきであり、2つのオブジェクトが等しくない場合は同じハッシュコードを持つ場合も持たない場合もあります。
あなたのオブジェクトをHashMap(joachim-sauerからのコメントの後に編集された)のキーとして使ってみてください、そうすればあなたは問題に直面し始めるでしょう。契約はガイドラインであり、あなたに強いられるものではありません。
見てHashtables
、Hashmaps
、HashSets
などなど。彼らは皆ハッシュキーを彼らのキーとして保存します。起動時get(Object key)
パラメータのハッシュが生成され、与えられたハッシュで検索されます。
上書きしない場合hashCode()
そして、キーのインスタンスが変更されている(例えば、まったく問題にならない単純な文字列)、hashCode()
同じオブジェクトに対して2つの異なるハッシュコードが生成される可能性があります。map.get()
。
HashMap
。 - Joachim Sauer