20

私はいつも、Java の .equals() メソッドをオーバーライドして、作成したクラスに固有のものにする必要があると考えてきました。つまり、同じインスタンスへの 2 つの参照ではなく、2 つの異なるインスタンスの同等性を探すことです。しかし、デフォルトのオブジェクトの動作はそのままにして、同じクラスの 2 つのオブジェクトの同等性をテストするための新しいメソッドを作成する必要があると考えているように見える他のプログラマーに遭遇しました。

equals メソッドをオーバーライドすることの賛成意見と反対意見は何ですか?

4

7 に答える 7

19

標準ライブラリ クラスで等価性をテストする場合 (たとえば、java.util.Set に一意の要素が含まれていることを確認したり、java.util.Map オブジェクトでオブジェクトをキーとして使用したりする場合) は、equals メソッドをオーバーライドする必要があります。

equals をオーバーライドする場合は、ドキュメントに記載されている API コントラクトを尊重するようにしてください。たとえば、Object.hashCodeもオーバーライドするようにしてください。

equals(Object) メソッドに従って 2 つのオブジェクトが等しい場合、2 つのオブジェクトのそれぞれで hashCode メソッドを呼び出すと、同じ整数結果が生成される必要があります。

編集:私はこれを主題に関する完全な回答として投稿しなかったので、equals のオーバーライドがimmutable objectsに最適であるという Fredrik Kalseth の声明をエコーし​​ます。Mapの API を引用するには:

注: 変更可能なオブジェクトをマップ キーとして使用する場合は、細心の注意を払う必要があります。オブジェクトがマップ内のキーであるときに、等値比較に影響を与える方法でオブジェクトの値が変更された場合、マップの動作は指定されません。

于 2008-08-19T17:14:47.760 に答える
8

私は、Effective Java のコピーを手に取り、項目 7 を読んで、equals contractに従うことを強くお勧めします。変更可能なオブジェクトの equals をオーバーライドする場合は注意が必要です。Maps や Sets などのコレクションの多くは equals を使用して等価性を判断しており、コレクションに含まれるオブジェクトを変更すると予期しない結果が生じる可能性があります。Brian Goetz も、equals と hashCode の実装について非常に優れた概要を説明しています。

于 2008-08-19T17:21:29.057 に答える
4

可変オブジェクトの equals と getHashCode を「決して」オーバーライドしないでください。これは、.net と Java の両方に当てはまります。そのようなオブジェクトを f.ex a ディクショナリのキーとして使用し、そのオブジェクトを変更すると、ディクショナリがハッシュコードに依存してオブジェクトを見つけるため、問題が発生します。

このトピックに関する良い記事は次のとおりです。 http://weblogs.asp.net/bleroy/archive/2004/12/15/316601.aspx

于 2008-08-19T17:28:02.507 に答える
2

@David Schlosnagleは、JoshBlochのEffectiveJavaについて言及しています。これはJava開発者にとって必読です。

関連する問題があります。不変の値オブジェクトの場合は、オーバーライドも検討する必要がありますcompare_to。それらが異なる場合の標準的な表現は、ComparableAPIにあります。

一般的にはそうですが、厳密には(compare(x、y)== 0)==(x.equals(y))である必要はありません。一般的に、この条件に違反するコンパレータは、この事実を明確に示す必要があります。推奨される言語は「注:このコンパレータは、equalsと矛盾する順序を課します」です。

于 2008-08-19T20:46:45.007 に答える
0

Equals メソッドは、参照を比較するためのものです。そのため、動作を変更するためにオーバーライドするべきではありません。

必要に応じて、異なるインスタンスで等価性をテストする新しいメソッドを作成する必要があります (または、一部の .NET クラスで CompareTo メソッドを使用します)。

于 2008-08-19T17:08:39.660 に答える
0

ソートされたデータ構造 (など)equals()にオブジェクトを追加するときに特定の動作が必要な場合にのみ、メソッドをオーバーライドする必要があります。SortedSet

それを行うときは、 もオーバーライドする必要がありますhashCode()

完全な説明については、こちらを参照してください。

于 2008-08-19T17:15:41.157 に答える
0

正直なところ、Java ではequalsをオーバーライドすることに反対する議論は実際にはありません。インスタンスが等しいかどうかを比較する必要がある場合は、それを行います。

前述のように、hashCodeとのコントラクトに注意する必要があります。同様に、Comparableインターフェースの落とし穴にも注意してください。ほぼすべての状況で、 Comparable によって定義された自然な順序付けを equals と一致させる必要があります ( BigDecimalを参照)。標準的なカウンターの例の api doc)

既存のライブラリ クラスを操作しないことは別として、同等性を判断するための新しいメソッドを作成することは、Java の規則に多少反します。

于 2008-08-19T19:50:42.967 に答える