私の同僚はequals()
メソッドをオーバーライドしていました。私の回答は、メソッドもオーバーライドしましたhashCode()
か? 彼の反応は、ハッシュ マップまたはハッシュ セットを使用しないためhashCode()
です。あれは正しいですか?
6 に答える
はい、彼は事実上正しいです-しかし、ある日オブジェクトをハッシュベースのコレクションに入れる必要がある場合、ハッシュコードをどこにでも追加する必要があります。 equals を使用) equals メソッドの微妙な点を見逃しているため...
ほとんどの IDE が自動 equals/hashcode 生成機能を提供していることを考えると、両方を作成しない理由はほとんどないと思います。
別の見方をすると、親クラスのメソッドをオーバーライドするときは、その親クラスによって定義された契約に従う必要があります。Object の場合、equals の javadocは非常に明確です。
通常、このメソッドがオーバーライドされるときは常に、hashCode メソッドをオーバーライドする必要があることに注意してください。これは、等しいオブジェクトには等しいハッシュ コードが必要であるという、hashCode メソッドの一般的な契約を維持するためです。
したがって、hashcode をオーバーライドしない本当の設計上の理由がない限り、デフォルトの決定は、親クラスの規約に従い、どちらもオーバーライドしないか、両方をオーバーライドすることです。
をオーバーライドする場合は、同様equals()
にオーバーライドhashCode()
します。今は使わなくてもhashCode()
、誰かが使うかもしれません。
このトピックの詳細については、優れたSO 回答を確認してください
コードの匂いです。たとえば、他のものをオーバーライドせずに hashCode または equals のいずれかをオーバーライドすると、Findbugs は警告を発します。相互に一貫性があるように両方をオーバーライドする必要があります (つまり、a.equals(b) => a.hashCode() == b.hashCode())。
ここで少し努力するだけで、後で多くの頭痛の種を回避できる可能性があります。
equals をオーバーライドするすべてのクラスで hashCode をオーバーライドする必要があります。そうしないと、Object.hashCode の一般規約に違反し、HashMap、HashSet、および Hashtable を含むすべてのハッシュベースのコレクションと連携して、クラスが適切に機能しなくなります。
有効な Java 項目 9: equals をオーバーライドするときは常に hashCode をオーバーライドします。
クラスが public クラスの場合、将来の開発でクラスがどのように使用されるかを制御することはできません。ソース コードを調べずに (またはリフレクションを介して)、このクラスが hasCode メソッドをオーバーライドしたかどうかを知る方法はなく、ハッシュ ベースのコレクションで使用すると、ユーザーはその結果に驚かれることでしょう。
実際には、equalsメソッドとhashCodeメソッドをオーバーライドせずに2つの異なるオブジェクトを作成するとします。そして、equalsメソッドを呼び出すと、javaはhashCodeメソッドを暗黙的に呼び出し、ハッシュコードの同等性をチェックします。
2つのオブジェクトの同等性をチェックするには、hashCodeメソッドをオーバーライドするだけで十分です。そして、それは将来のために役立つでしょう。このクラスはコレクションで使用できます。
それ以外の場合、equalメソッドを実装すると、2つのオブジェクトの同等性だけが解決されます。
全般的:
独自の方法で使用したいメソッドと、このオーバーライドの影響を受けるメソッドのみをオーバーライドしてください。
質問に固有:
Javaドキュメントから、
equals() メソッドがオーバーライドされるときは常に hashCode メソッドをオーバーライドする必要があることに注意してください。これは、等しいオブジェクトには等しいハッシュ コードが必要であるという hashCode メソッドの一般的な規約を維持するためです。