web-dev-qa-db-ja.com

.equals()がJavaのクラスにあるのに、.compareTo()がインターフェースにあるのはなぜですか?

_.equals_のようなメソッドが Comparable クラスにあるのに、.compareTo()Object インターフェイスにある理由を知りたいです。私にとって、.compareTo()のようなメソッドがObjectクラスに含まれていない理由は任意です。

.compareTo()を使用するには、Comparableインターフェースを実装し、目的に応じて.compareTo()メソッドを実装します。 .equals()メソッドの場合、すべてのクラスがObjectクラスを継承するため、クラスのメソッドをオーバーライドするだけです。

私の質問は、Objectのようなクラスではなく、実装するインターフェイスに.compareTo()のようなメソッドがあるのはなぜですか?同様に、一部のインターフェイスではなく、クラスObject.equals()メソッドが実装されるのはなぜですか?

30
Wesley

すべてのオブジェクトを比較できるわけではありませんが、すべてのオブジェクトが等しいかどうかを確認できます。他に何もない場合は、メモリ内の同じ場所に2つのオブジェクトが存在するかどうかを確認できます(参照等価)。

2つのThreadオブジェクトに対するcompareTo()の意味は何ですか?あるスレッドが別のスレッドより「大きい」とはどういう意味ですか? 2つのArrayList<T>sをどのように比較しますか?

Objectコントラクトはall Javaクラスに適用されます。1つのクラスでもそれ自体のクラスの他のインスタンスと比較できない場合、Objectは、インターフェースの一部であることを要求できません。

ジョシュア・ブロッホは、「自然順序付け」というキーワードを説明するときに使用しますwhyクラスがComparableを実装したいと思うかもしれません。上記の例で述べたように、すべてのクラスに自然な順序があるわけではないため、すべてのクラスがComparableを実装したり、ObjectcompareToメソッドを実装したりする必要はありません。

...compareToメソッドはObjectで宣言されていません。 ...これはObjectequalsメソッドに似ていますが、単純な等価比較に加えて順序比較が可能であり、汎用的です。 Comparableを実装すると、クラスはそのインスタンスに自然順序付けがあることを示します。

Effective Java、Second Edition :Joshua Bloch。項目12、62ページ。省略記号は、他の章やコード例への参照を削除します。

doが自然な順序付けのないComparableクラス以外のクラスに順序付けを課したい場合は、いつでもComparatorインスタンスを指定して支援することができますそれを並べ替えます。

58
user22815

JLS§4.3.2 は、classオブジェクトを次のように定義します。

4.3.2。クラスオブジェクト

クラスObjectは、他のすべてのクラスのスーパークラス(§8.1.4)です。

すべてのクラスおよび配列型は、クラスObjectのメソッドを継承します(§8.4.8)。これは、次のように要約されます。

  • メソッドcloneは、オブジェクトの複製を作成するために使用されます。

  • メソッドequalsは、参照ではなく値に基づくオブジェクトの等価性の概念を定義します。

  • メソッドfinalizeは、オブジェクトが破棄される直前に実行されます(§12.6)。

  • メソッドgetClassは、オブジェクトのクラスを表すClassオブジェクトを返します。

  • 参照タイプごとにClassオブジェクトが存在します。これは、たとえば、クラスの完全修飾名、そのメンバー、その直接のスーパークラス、およびそれが実装するインターフェースを検出するために使用できます。

    getClassのメソッド呼び出し式のタイプはClass<? extends |T|>です。ここで、TgetClassを検索するクラス(15.12.1)です。

    synchronized(§8.4.3.6)と宣言されたクラスメソッドは、クラスのClassオブジェクトに関連付けられたモニターで同期します。

  • メソッドhashCodeは、メソッドequalsとともに、Java.util.Hashmapなどのハッシュテーブルで非常に役立ちます。

  • メソッドwaitnotify、およびnotifyAllは、スレッドを使用した並行プログラミングで使用されます(§17.2)。

  • メソッドtoStringは、オブジェクトの文字列表現を返します。

そのため、equalsObjectにありますが、compareToは別のインターフェイスにあります。私は、彼らがObjectをできるだけ最小限に抑えたかったのではないかと推測します。彼らはおそらくほぼすべてObjectsにはequalshashCodeが必要だと考えました(これは実際には同等性テストの形式)ですが、すべてのオブジェクトがorderingの概念を持つ必要があるわけではありません。これがcompareToの使用目的です。

8
durron597

スノーマンの優れた答えに加えて、Comparableは長い間一般的なインターフェースでした。型はcompareTo(object)を実装せず、compareTo(T)を実装します。ここで、Tは独自の型です。 objectは、それから派生するクラスを認識していないため、これをobjectに実装することはできません。

objectcompareTo(object)メソッドを定義できたかもしれませんが、これによりSnowmanが指摘したことだけでなく、2つのArrayList<T>sまたは2つのThreadsの間、ただしArrayList<T>およびThread。それはもっと無意味です。

2
hvd

2つのオブジェクト参照があるとします。Xは、コンテンツ "George"を保持するStringのインスタンスを識別します。 Yは、座標[12,34]を保持するPointのインスタンスを識別します。次の2つの質問を検討してください。

  • XとYは同等のオブジェクトを識別しますか?

  • XはYの前、後、またはYと同等にソートする必要がありますか?

XとYが無関係の型のインスタンスを識別するという事実は、最初の質問を検討するときに問題にはなりません。オブジェクトは、それらのタイプが同等であると定義する共通のベースを共有している場合にのみ同等と見なされます。 StringPointにはそのようなベースがないため(共通のベースタイプのみがすべての個別のオブジェクトを同等ではないと見なす)、答えは単に「いいえ」です。

ただし、タイプが無関係であることは、2番目の質問に関して大きな問題を引き起こします。一部のタイプはインスタンス間の順序関係を定義し、一部の順序関係は複数のタイプに及ぶ場合もあります[例: BigIntegerBigDecimalは、どちらかのタイプのインスタンスをもう一方のインスタンスに対して相対的にランク付けできるようにする比較メソッドを定義することができます]が、一般に2つを取ることはできません。任意のインスタンスを作成し、「XをYの前、後、またはYと同等にソートする必要があるか」を尋ね、全体の順序を導き出します。オブジェクトがconsistentであるがtotalではなく順序付けを報告する必要がある場合、「XをYに関して前、後、同等、またはランク付けしないでください」と尋ねることができます。 1つですが、ほとんどの並べ替えアルゴリズムでは、完全な順序付けが必要です。したがって、「unranked」が有効な戻り値である場合、すべてのオブジェクトがcompareToメソッドを実装できたとしても、そのようなメソッドは、その存在を正当化するのに十分役立ちません。

0
supercat