目次
equals メソッドをオーバーライドしない" >equals メソッドをオーバーライドしない
equals メソッドをオーバーライドする" >equals メソッドをオーバーライドする
コレクション内のequalsメソッドの同値関係" >コレクション内のequalsメソッドの同値関係
equalsメソッドの書き方" >equalsメソッドの書き方
equalsの実装に関する注意点" >equalsの実装に関する注意点
ホームページ Java &#&チュートリアル Java で等号をオーバーライドするより詳細なメソッドの概要

Java で等号をオーバーライドするより詳細なメソッドの概要

Apr 24, 2017 pm 04:07 PM

最近、私は同僚とイコールと == の違いについて話していました。これは実際には非常に古くて単純な質問ですが、equals メソッドを自分でオーバーライドしたい場合、知らないことはあっても知っておく必要があることがいくつかあることがわかります。同等の内容をカバーするには多大な注意が必要です。 Object は非常に特殊なクラスですが、その主な役割は拡張することです。その非最終メソッドにはすべて、明確な 普遍的な規約 があります。これらはメソッドをオーバーライドするように設計されているためです。 equals、hashCode、toString、clone、およびfinalizeをオーバーライドするクラスは、これらのメソッドの一般的な規則に準拠する必要があります。これができないと、複数のクラスを組み合わせたときに望ましい効果を達成することが困難になります。

equals メソッドをオーバーライドしない


equals メソッドをオーバーライドするのは簡単そうに見えますが、エラーを引き起こす可能性のあるオーバーライド メソッドが多数あります。このエラーを回避する最も簡単な方法は、equals をオーバーライドしないことです。この場合、各クラス インスタンスはそれ自体とのみ等しくなります。では、どのような状況で、equals メソッドをオーバーライドしないことを選択できるのでしょうか?

クラスの各インスタンスは本質的に一意です

これは、各スレッド インスタンスなど、値ではなくアクティブなエンティティを表すクラスに当てはまります。各スレッドは一意であるため、equals メソッドと比較することは無意味です。この場合、Object クラスの equals で完全に十分であるため、equals メソッドをオーバーライドする必要はありません。

オブジェクトクラスでのequalsメソッドの実装:

 public boolean equals(Object obj) { return (this == obj);  }
ログイン後にコピー
ログイン後にコピー

クラスが論理的等価判定を必要とするかどうかは気にしません

一部のクラスは「数値クラス」であり、サイズの比較と数学的演算は次の仕事です。これらのクラス。この場合、クラスに格納されている値を比較し、論理的等しいかどうかを判断する必要があります。クラスに加えて、ほとんどのクラスには「一方が他方と等しいかどうか」という概念がありません。論理的等価性を考慮しないこのようなクラスは、equals メソッドをオーバーライドする必要はありません。

スーパークラスで実装されたequalsはサブクラスにも適用できます

例えば、AbstractSetクラスを継承したHashSetクラスのequalsメソッドに違いはなく、HashSetはAbstractSetのequalsメソッドを直接利用することができます。

equals メソッドをオーバーライドする

上記とは逆に、equals メソッドをオーバーライドする必要がある状況は次のとおりです。クラスに独自の論理的等価性の概念があり、親クラスに利用可能な equals メソッドのオーバーライドがない場合。現時点では、自分たちでカバーする必要があります。

コレクション内のequalsメソッドの同値関係


equalsメソッドは同値関係を実装します。離散数学における同値関係の概念を学びました。R 上の二項関係は、自発対称性と推移性を満たす場合、それは等価です。等しい値とこれら 3 つのプロパティの関係を詳しく分析してみましょう。

反射性: null 以外の参照値 x に対して、x.equals(x) は true を返さなければなりません

対称性: null 以外の参照値 x および y について、y が等しい場合にのみ ( x) は true を返します。x.equals(y) は true を返す必要があります

推移性: null 以外の参照値 x、y、z について、x.equals(y) が true を返す場合、y.equals ( z) も true を返す場合、x.equals(z) は true を返す必要があります。

反射性: ∀ a ∈A, => (a, a) ∈ R
対称性: (a, b) ∈R∧ a ≠ b => (b, a)∈R
推移性: (a, b) )∈R, (b, c)∈R =>(a, c)∈R

この3つの性質を比較してみても問題ありません。等価メソッドは同値関係を実現していることがわかります。

equalsメソッドの書き方


オブジェクトのequalsメソッドはアドレスを調べるだけですが、これでは明らかに要件を満たすことができません。では、equals メソッドを自分で作成する場合、高品質で論理的な比較メソッドを作成するにはどうすればよいでしょうか?等しいの記述は、次の 4 つのステップに要約できます:

1. == 演算子を使用して、パラメーターがオブジェクトへの単なる参照であるかどうかを確認します
結果が等しい場合は、x を示す true が返されます。と y はオブジェクトへの異なる参照であり、判断する必要はありません。

2. パラメータの型が正しいかどうかを確認するには、instanceof 演算子を使用します 結果が正しい型ではない場合は、false を返します。equals メソッドは Object クラスから継承するため、パラメータの型を回避することはできません。まず、instanceof を使用してパラメータのタイプを決定します。タイプが正しくない場合は、次のステップに進む必要はありません。

3. パラメータを正しい型に変換します 検出は以前に行われているため、このステップでの型変換は問題ありません。

4. 各クラスで論理的に比較する必要があるドメイン値を判断します x と y が同じ型の異なるインスタンスであることを確認し、判断する必要があるドメイン値を取り出すだけです論理比較を行い、比較判定を行います。すべてが正しい場合は true を返し、そうでない場合は false を返します。

equalsの実装に関する注意点


equalsメソッドを書いた後は、再帰性、対称性、推移性を満たしているかどうかを繰り返し判断する必要があります。それだけではなく、平等性を確保しながらequalsメソッドを記述する際に注意すべき点がいくつかあり、これを改善する必要があります。

equalsメソッドをオーバーライドするときは必ずhashCodeメソッドをオーバーライドする
ハッシュ関連のクラスを書く場合は、equalsメソッドをオーバーライドするときにhashCodeメソッドもオーバーライドする必要があります。ハッシュ テーブルでは、論理的に同一のオブジェクトは同じハッシュ コードを持つ必要があるためです。比較的単純な例を挙げると、HashSet に String を格納します。== を使用すると、同じ内容を持つ 2 つの String 文字列が false と判断される可能性がありますが、HashSet にはそれらのコピーが 1 つだけ存在します。これは、同じロジックの String は同じ hashCode を持つためです。
一般に、クラスのequalsメソッドをオーバーライドすると、特定の状況下では2つの異なるオブジェクトが論理的に等しいことが証明されます。現時点でハッシュに関連している場合、2 つのオブジェクトには同じ hashCode が必要です。したがって、equals メソッドをオーバーライドする場合は、必ず hashCode メソッドをオーバーライドしてください。

equalsメソッドをあまりスマートにしないでください
上記の実装手順に従ってequalsメソッドを書くだけであれば、規定に準拠しており、変なエラーは発生しません。しかし、さまざまな派手な等価関係を追求することに固執してコードを肥大化させると、本来の凝集性の高さという意図に反するだけでなく、コード内に不可解なエラーが発生することがあります。

equals メソッドのパラメータの型を間違えないでください
言うとおかしいと思うかもしれませんが、これが実際に起こることです。パラメーターの型を変更した後、equals メソッドは Object クラスとは何の関係もなくなるため、コンパイラーはエラーを報告しなくなり、プログラマーにとっては終わりのない頭痛の種だけが残ります。パラメーターの型がオブジェクトであることに気づかないと、プログラムがなぜ正しく動作しないのか考えて何時間も費やすことになるでしょう。

最近、私は同僚とイコールと == の違いについて話していました。これは実際には非常に古くて単純な質問ですが、equals メソッドを自分でオーバーライドしたい場合、知らないことはあっても知っておく必要があることがいくつかあることがわかります。同等の内容をカバーするには多大な注意が必要です。 Object は非常に特殊なクラスですが、その主な役割は拡張することです。その非最終メソッドにはすべて、明確な 普遍的な規約 があります。これらはメソッドをオーバーライドするように設計されているためです。 equals、hashCode、toString、clone、およびfinalizeをオーバーライドするクラスは、これらのメソッドの一般的な規則に準拠する必要があります。これができないと、複数のクラスを組み合わせたときに望ましい効果を達成することが困難になります。

equals メソッドをオーバーライドしない


equals メソッドをオーバーライドするのは簡単そうに見えますが、エラーを引き起こす可能性のあるオーバーライド メソッドが多数あります。このエラーを回避する最も簡単な方法は、equals をオーバーライドしないことです。この場合、各クラス インスタンスはそれ自体とのみ等しくなります。では、どのような状況で、equals メソッドをオーバーライドしないことを選択できるのでしょうか?

クラスの各インスタンスは本質的に一意です

これは、各スレッド インスタンスなど、値ではなくアクティブなエンティティを表すクラスに当てはまります。各スレッドは一意であるため、equals メソッドと比較することは無意味です。この場合、Object クラスの equals で完全に十分であるため、equals メソッドをオーバーライドする必要はありません。

オブジェクトクラスでのequalsメソッドの実装:

 public boolean equals(Object obj) { return (this == obj);  }
ログイン後にコピー
ログイン後にコピー

クラスが論理的等価判定を必要とするかどうかは気にしません

一部のクラスは「数値クラス」であり、サイズの比較と数学的演算は次の仕事です。これらのクラス。この場合、クラスに格納されている値を比較し、論理的等しいかどうかを判断する必要があります。クラスに加えて、ほとんどのクラスには「一方が他方と等しいかどうか」という概念がありません。論理的等価性を考慮しないこのようなクラスは、equals メソッドをオーバーライドする必要はありません。

スーパークラスで実装されたequalsはサブクラスにも適用できます

例えば、AbstractSetクラスを継承したHashSetクラスのequalsメソッドに違いはなく、HashSetはAbstractSetのequalsメソッドを直接利用することができます。

equals メソッドをオーバーライドする

上記とは逆に、equals メソッドをオーバーライドする必要がある状況は次のとおりです。クラスに独自の論理的等価性の概念があり、親クラスに利用可能な equals メソッドのオーバーライドがない場合。現時点では、自分たちでカバーする必要があります。

コレクション内のequalsメソッドの同値関係


equalsメソッドは同値関係を実装します。離散数学における同値関係の概念を学びました。R 上の二項関係は、自発対称性と推移性を満たす場合、それは等価です。等しい値とこれら 3 つのプロパティの関係を詳しく分析してみましょう。

反射性: null 以外の参照値 x に対して、x.equals(x) は true を返さなければなりません

対称性: null 以外の参照値 x および y について、y が等しい場合にのみ ( x) は true を返します。x.equals(y) は true を返す必要があります

推移性: null 以外の参照値 x、y、z について、x.equals(y) が true を返す場合、y.equals ( z) も true を返す場合、x.equals(z) は true を返す必要があります。

反射性: ∀ a ∈A, => (a, a) ∈ R
対称性: (a, b) ∈R∧ a ≠ b => (b, a)∈R
推移性: (a, b) )∈R, (b, c)∈R =>(a, c)∈R

この3つの性質を比較してみても問題ありません。等価メソッドは同値関係を実現していることがわかります。

equalsメソッドの書き方


オブジェクトのequalsメソッドはアドレスを調べるだけですが、これでは明らかに要件を満たすことができません。では、equals メソッドを自分で作成する場合、高品質で論理的な比較メソッドを作成するにはどうすればよいでしょうか?等しいの記述は、次の 4 つのステップに要約できます:

1. == 演算子を使用して、パラメーターがオブジェクトへの単なる参照であるかどうかを確認します
結果が等しい場合は、x を示す true が返されます。と y はオブジェクトへの異なる参照であり、判断する必要はありません。

2. パラメータの型が正しいかどうかを確認するには、instanceof 演算子を使用します 結果が正しい型ではない場合は、false を返します。equals メソッドは Object クラスから継承するため、パラメータの型を回避することはできません。まず、instanceof を使用してパラメータのタイプを決定します。タイプが正しくない場合は、次のステップに進む必要はありません。

3. パラメータを正しい型に変換します 検出は以前に行われているため、このステップでの型変換は問題ありません。

4. 各クラスで論理的に比較する必要があるドメイン値を判断します x と y が同じ型の異なるインスタンスであることを確認し、判断する必要があるドメイン値を取り出すだけです論理比較を行い、比較判定を行います。すべてが正しい場合は true を返し、そうでない場合は false を返します。

equalsの実装に関する注意点


equalsメソッドを書いた後は、再帰性、対称性、推移性を満たしているかどうかを繰り返し判断する必要があります。それだけではなく、平等性を確保しながらequalsメソッドを記述する際に注意すべき点がいくつかあり、これを改善する必要があります。

equalsメソッドをオーバーライドするときは必ずhashCodeメソッドをオーバーライドする
ハッシュ関連のクラスを書く場合は、equalsメソッドをオーバーライドするときにhashCodeメソッドもオーバーライドする必要があります。ハッシュ テーブルでは、論理的に同一のオブジェクトは同じハッシュ コードを持つ必要があるためです。比較的単純な例を挙げると、HashSet に String を格納します。== を使用すると、同じ内容を持つ 2 つの String 文字列が false と判断される可能性がありますが、HashSet にはそれらのコピーが 1 つだけ存在します。これは、同じロジックの String は同じ hashCode を持つためです。
一般に、クラスのequalsメソッドをオーバーライドすると、特定の状況下では2つの異なるオブジェクトが論理的に等しいことが証明されます。現時点でハッシュに関連している場合、2 つのオブジェクトには同じ hashCode が必要です。したがって、equals メソッドをオーバーライドする場合は、必ず hashCode メソッドをオーバーライドしてください。

equalsメソッドをあまりスマートにしないでください
上記の実装手順に従ってequalsメソッドを書くだけであれば、規定に準拠しており、変なエラーは発生しません。しかし、さまざまな派手な等価関係を追求することに固執してコードを肥大化させると、本来の凝集性の高さという意図に反するだけでなく、コード内に不可解なエラーが発生することがあります。

equals メソッドのパラメータの型を間違えないでください
言うとおかしいと思うかもしれませんが、これが実際に起こることです。パラメーターの型を変更した後、equals メソッドは Object クラスとは何の関係もなくなるため、コンパイラーはエラーを報告しなくなり、プログラマーにとっては終わりのない頭痛の種だけが残ります。パラメーターの型がオブジェクトであることに気づかないと、プログラムがなぜ正しく動作しないのか考えて何時間も費やすことになるでしょう。

以上がJava で等号をオーバーライドするより詳細なメソッドの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

Java での日付までのタイムスタンプ Java での日付までのタイムスタンプ Aug 30, 2024 pm 04:28 PM

Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

カプセルの量を見つけるためのJavaプログラム カプセルの量を見つけるためのJavaプログラム Feb 07, 2025 am 11:37 AM

カプセルは3次元の幾何学的図形で、両端にシリンダーと半球で構成されています。カプセルの体積は、シリンダーの体積と両端に半球の体積を追加することで計算できます。このチュートリアルでは、さまざまな方法を使用して、Javaの特定のカプセルの体積を計算する方法について説明します。 カプセルボリュームフォーミュラ カプセルボリュームの式は次のとおりです。 カプセル体積=円筒形の体積2つの半球体積 で、 R:半球の半径。 H:シリンダーの高さ(半球を除く)。 例1 入力 RADIUS = 5ユニット 高さ= 10単位 出力 ボリューム= 1570.8立方ユニット 説明する 式を使用してボリュームを計算します。 ボリューム=π×R2×H(4

Spring Tool Suiteで最初のSpring Bootアプリケーションを実行するにはどうすればよいですか? Spring Tool Suiteで最初のSpring Bootアプリケーションを実行するにはどうすればよいですか? Feb 07, 2025 pm 12:11 PM

Spring Bootは、Java開発に革命をもたらす堅牢でスケーラブルな、生産対応のJavaアプリケーションの作成を簡素化します。 スプリングエコシステムに固有の「構成に関する慣習」アプローチは、手動のセットアップを最小化します。

See all articles