クラスはいつComparableやComparatorにする必要がありますか?


138

ComparableComparatorの両方を実装するクラスを見てきました。これは何を意味するのでしょうか?なぜ一方を他方で使用するのですか?


18
それらのjavadocを読みましたか?違いをかなり明確に説明しています。
skaffman 2009

1
比較対象と比較対象とは何か、比較対象と比較対象を使用するタイミング。これらを知るには、このリンクを読んでください。これは、それらの動作と使用法を理解するのに役立ちます。http://iandjava.blogspot.in/2012/10/comparable-and-comparator.html
RockStar '10 / 10/26

6
これは、良い客観的な答えを持つ良い質問です。閉まっているのが残念です。
ラッセルシルバ

3
StackOverflowに関する他の質問では、これを「コンパレータと比較可能なものの違いは何ですか」という決定的な質問と呼んでいます。なぜ「建設的でない」とマークされているのですか?Java初心者として、これは非常に役立つ質問でした!
ピート

回答:


241

以下のテキストは、比較対比較可能です

同程度の

比較可能なオブジェクトは、それ自体を別のオブジェクトと比較することができます。クラス自体は、java.lang.Comparableそのインスタンスを比較できるようにするために、インターフェースを実装する必要があります。

コンパレータ

コンパレータオブジェクトは、2つの異なるオブジェクトを比較できます。クラスはそのインスタンスを比較していませんが、他のいくつかのクラスのインスタンスを比較しています。このコンパレータクラスは、java.util.Comparatorインターフェイスを実装する必要があります。


コンパレータと比較の両方の使用法の詳細な説明については、sysdotoutdotprint.com
index.php


@ mel3kings-リンクにアクセスできなくなりました。
Gaurav

152

実装とComparableは、「自分を別のオブジェクトと比較できること」意味します。これは通常、単一の自然なデフォルト比較がある場合に役立ちます。

実装とComparatorは、「他の2つのオブジェクトを比較できること」意味します。これは通常、型の2つのインスタンスを比較する方法が複数ある場合に便利ですたとえば、年齢、名前などで人を比較できます。


1
こんにちはスキート、比較コードとコンパレータを使用してコードを削除してください。
Mdhar9e

5
@ mdhar9e:周りには多くの例があります-それらを特定のシナリオに変換するのが難しいと感じた場合は、新しい質問で詳細をお知らせください。
ジョンスキート、

2
@alireza:すでに2番目の段落で例を示しました。異なるコンパレータを使用することで、同じコレクション(人)を異なるプロパティ(年齢、名前など)で並べ替えることができます。これは、Personimplement を作成するだけでは実行できません。2人の比較方法Comparableを変更することはできないためです。
Jon Skeet 2014年

1
@feelgoodandprogramming:いいえ、これらは異なるソートアルゴリズムです。ここには、3つの異なるクラスの3つのコードが含まれている可能性があります。1)エンティティ自体Person。2)コンパレータ。たとえば、PersonAgeComparator2つの異なるエンティティを比較し、特定のソート順で最初に来るエンティティを決定できます。3)エンティティのコレクションとコンパレーターを受け取り、コンパレーターを使用してそのコレクションをソートして、順序を決定するソートコード。
Jon Skeet、2014

2
@RishiKeshPathak:比較対象が1つしかない場合は、Comparableを使用するだけでは不十分です。そして、それでもあなた単にコンパレータを書くことができます。同じクラスを使用する2つの異なるプログラムがあり、1つは年齢だけで、もう1つは名前だけで並べ替えたい場合、少なくとも1つはコンパレータを使用する必要があります。
Jon Skeet、2014

38

Comparableにより、クラスは独自の比較を実装できます。

  • それは中だ同じクラス(それはしばしば有利です)
  • 実装は1つしかありません(そのため、2つの異なるケースが必要な場合は使用できません)

比較すると、コンパレータは外部比較です。

  • 通常、一意のインスタンス(同じクラスまたは別の場所)にあります
  • 各実装に、ソートしたい方法で名前付けます
  • 管理していないクラスにコンパレータを提供できます
  • 最初のオブジェクトがnullであっても、実装は使用可能です

どちらの実装でも、比較対象を選択できます。ジェネリックスを使用すると、そのように宣言して、コンパイル時にチェックすることができます。これにより安全性が向上しますが、適切な値を決定することも課題です。

ガイドラインとして、私は通常、そのオブジェクトを比較できる最も一般的なクラスまたはインターフェイスを使用します。想定するすべてのユースケースで...定義はそれほど正確ではありませんが!:-(

  • Comparable<Object>コンパイル時にすべてのコードでそれを使用できるようにします(必要な場合はこれで十分であり、そうでない場合は不良であり、コンパイル時のエラーが発生します)。実装はオブジェクトに対処し、必要に応じて堅牢な方法でキャストする必要があります。
  • Comparable<Itself> 逆に非常に厳しいです。

おもしろいことに、それ自体をサブクラスにサブクラス化する場合、サブクラスも比較可能であり、それに対して堅牢でなければなりません(そうしないと、リスコフの原則が破られ、実行時エラーが発生します)。


20

java.lang.Comparable

  1. Comparableインターフェイスを実装するには、クラスは単一のメソッドを実装する必要がありますcompareTo()

    int a.compareTo(b)

  2. インスタンスをソートするクラスを変更する必要があります。したがって、クラスごとに1つの分類順序しか作成できません。

java.util.Comparator

  1. コンパレータインターフェイスを実装するには、クラスは単一のメソッドを実装する必要があります compare()

    int compare (a,b)

  2. インスタンスをソートするクラスとは別のクラスを作成します。そのため、クラスごとに複数のソートシーケンスを作成できます。

14

Comparable たとえば、データオブジェクトに自然な順序がある場合など、データオブジェクトにデフォルトの順序を提供するためです。

A Comparatorは、特定の用途の順序自体を表します。


8

Comparable通常は推奨されます。ただし、クラスがすでにを実装していることComparableがありますが、別のプロパティでソートしたい場合があります。次に、使用を余儀なくされますComparator

一部のクラスは実際Comparatorsに一般的なケースを提供します。たとえば、Stringsがデフォルトの大文字と小文字を区別しソートでですが、静的もありますComparator呼ばれるがCASE_INSENSITIVE_ORDER


7
Comparableが優先されることに同意するかどうかはわかりません。一部のオブジェクトは、自然な順序、つまりすべての形式の数値(自然数、実数、日付など)を強く持っています。しかし、文字列のような他の比較的原始的なオブジェクトでさえ、普遍的に適用できる順序がありません。アプリケーションドメインモデルのエンティティのようなより複雑なオブジェクトの場合、通常、Comparableの実装は誤りです。それらの多くの特性により、どの順序が最も頻繁に必要になるかを予測するのが非常に困難になります。
エリクソン2009

6

ここに私がウェブで見つけたコンパレータと比較可能なものの間のいくつかの違いがあります:

  1. あなたが見るなら、これらの2つの間の論理的な違いは、Javaのコンパレータが彼に提供された2つのオブジェクトを比較するのに対し、Comparableインターフェースは「this」参照を指定されたオブジェクトと比較することです。

  2. JavaのComparableは、オブジェクトの自然な順序付けを実装するために使用されます。Java API文字列では、DateクラスとラッパークラスがComparableインターフェースを実装します。

  3. クラスがJavaでComparableインターフェースを実装している場合、ListまたはArrayのいずれかのオブジェクトのコレクションは、Collections.sort()またはArray.sort()メソッドを使用して自動的にソートでき、オブジェクトはCompareToメソッドで定義された自然な順序に基づいてソートされます。

  4. JavaでComparableを実装するオブジェクトは、コンパレータを指定せずに、ソート済みマップのキーまたはTreeSetなどのソート済みセットの要素として使用できます。

site:JavaでComparatorとComparableを使用する方法 例で

続きを読む:JavaでComparatorとComparableを使用する方法?例で


5

Comparable自然な順序のオブジェクト用です。オブジェクト自体は、それがどのように順序付けられるかを知っています。
Comparator自然な順序付けのないオブジェクト、または別の順序付けを使用する場合に使用します。


4

コンパレータと比較可能なインターフェースの違い

Comparable 別のオブジェクトと使用して自身を比較するために使用されます。

Comparator オブジェクトである2つのデータ型を比較す​​るために使用されます。


2

あなたが見るならば、これらの2つの間の論理的な違いはComparatorJavaで彼に提供された2つのオブジェクトを比較する一方で、Comparableインターフェースは「this」参照を指定されたオブジェクトと比較します。

ComparableJavaでは、オブジェクトの自然な順序付けを実装するために使用されます。Java API文字列では、DateクラスとラッパークラスがComparableインターフェイスを実装します。

どのクラスが実装する場合Comparable、Javaのインターフェイスを、そのオブジェクトのコレクションのいずれかListまたはArray使用することによって、自動的にソートすることができるCollections.sort()か、Array.sort()方法及びオブジェクトは、で定義されてそこに自然な順序に基づいてソートされますcompareTo方法。

ComparableたとえばTreeSet、Java で実装するオブジェクトは、何も指定せずに、ソート済みマップのキーまたはソート済みセットの要素として使用できますComparator


0

ComparableおよびComparatorを実装するための私の注釈ライブラリ:

public class Person implements Comparable<Person> {         
    private String firstName;  
    private String lastName;         
    private int age;         
    private char gentle;         

    @Override         
    @CompaProperties({ @CompaProperty(property = "lastName"),              
        @CompaProperty(property = "age",  order = Order.DSC) })           
    public int compareTo(Person person) {                 
        return Compamatic.doComparasion(this, person);         
    }  
} 

リンクをクリックすると、他の例が表示されます。相応の


3
Stackoverflowへようこそ。この質問は古く、すでに回答されています。通常、応答が以前の応答とは大きく異なる、または異なる何かを提供しない限り、古いスレッドを復活させないことが最善です。
2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.