1

これらのインターフェイスがコレクション内のオブジェクトの並べ替えに使用することは知っています。しかし、私はそれらの本当の違いに疑問を持っています。私が読んだ1つの事実は、現在のオブジェクト(これ)なしで2つのオブジェクトを比較したい場合に比較可能なものを使用することです。

しかし、私の問題は、コンパレータを使用しても、同じオブジェクトタイプを比較することです。

ここで本当に違いは何ですか。私は混乱しています。次の例を考えてみましょう。

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

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public int compareTo(Person anotherPerson){     
    int anotherPersonAge =anotherPerson.getAge();  
    return this.age - anotherPersonAge;    
  }
}

コンパレーターを使用する場合、クラスにコンパレーターを実装させ、this.ageの代わりにperson.ageを実装します。では、ここでは何がそんなに違うのでしょうか?

public class LastNameComparator implements Comparator<Person> {
  public int compare(Person person, Person anotherPerson) {
    int age1 = person.getAge();
    int age2 = anotherPerson.getAge();

     return age1 - age2; 
  }
}

内部ロジックCollections.sortの使用法がわかりません。その点については、上記の点を正当化してください。

また、-1、1、または0の権利を返す必要はないと思います。上記の実装も有効ですよね?私が抱えている問題の1つは、1を返す場合、リストはどのようにアイテムを昇順または降順で並べ替えることができるかということです。その違いを考慮し、違いに応じて並べ替えると思いました。

4

5 に答える 5

1

両方のComparableのドキュメントを検討してください

このインターフェイスは、それを実装する各クラスのオブジェクトに全体的な順序付けを課します。この順序付けはクラスの自然順序付けと呼ばれ、クラスの compareTo メソッドはその自然比較メソッドと呼ばれます。

コンパレータ

オブジェクトのコレクションに全体的な順序付けを課す比較関数。コンパレーターを並べ替えメソッド (Collections.sort や Arrays.sort など) に渡して、並べ替え順序を正確に制御できます。コンパレータは、特定のデータ構造 (並べ替えられたセットや並べ替えられたマップなど) の順序を制御したり、自然な順序付けを持たないオブジェクトのコレクションに順序付けをしたりするためにも使用できます。

オブジェクトは、それ自体を別のComparableオブジェクトと比較することによってその順序を決定できます (自然順序付け)。一方、aComparatorは、2 つのオブジェクトを比較して特定の順序を決定する方法を知っているオブジェクトです。ここでの違いは、誰が比較の責任を負うかです。

自然順序付けでは定義済みの順序が課されcompareToますが、その順序を変更したい場合や、さらに悪いことに、定義済みの比較ロジックがない場合はどうでしょうか? オブジェクトに「ねえ、今度は年齢ではなく名前に従って注文する」という厄介なロジックではなくComparator、 new を発行することで動的に切り替えることができるさまざまな比較に基づいてコレクションをソートできるため、ここで便利です。 "。ComparatorComparable

比較結果の差異については、オブジェクトごとに確認します。たとえば、年齢10が 、 、 の153人を取り上げ20ます。15は と比較すると 1 を返しますが、 と比較すると を10返し、3 人の順序を定義します。-120

ニーズに合ったアプローチを選択してください。比較ロジックが安定しており、将来変更されない場合は、Comparableオブジェクトが必要になる可能性がありますが、さまざまな基準に基づいてコレクションを並べ替える必要がある場合は、Comparators を使用する必要があります。

于 2012-12-04T16:50:19.947 に答える
0

このように考えてみてください... 1 つの整数を持つ Class IntegerWrapperがあり、クラスにComparableを実装しました。Collection.sort を使用してこれらを並べ替えると、オブジェクトが昇順で表示されます...

ただし、この順序を変更して降順にしたい場合は、コンパレータを実装して目的の順序で並べ替える必要があります...

于 2012-12-04T16:58:05.367 に答える
0

Comparable インターフェースを使用する人がいると、私は常に恐怖を感じます。なぜなら、それはほとんど常に間違った選択だからです。Comparable は、並べ替えではなく、自然な順序を定義するために使用されます。Java は、満たす必要がある equals-hashcode コントラクトを認識しています。ほとんどの開発者はそれを知っています。しかし、もう 1 つの重要な契約があります。対等比較契約です。

つまり、次のことを意味します。

a.equals(b) <==> a.compareTo(b) == 0

あなたの例では、1 つの TreeSet に同じ年齢の 2 人の異なる人物を含めることはできません。

于 2014-05-06T20:43:36.757 に答える
0

Java では、型は常に一度だけインターフェースを実装できます。つまり、言うことはできません。

public class Foo implements Comparable<Foo>, Comparable<String> {}

これは、 のインスタンスFooが常に特定の方法でソートされることを意味します。特定のコンテキストではソートをある方法で実行し、別のコンテキストでは異なる方法でソートすることはできません。

一方Comparator、 は、ソートできるインスタンスに依存しません。1 つの型に対して、をいくつでも持つことができますComparator(正確に 1 つではなくComparable)。特定の並べ替えが必要な場合は、新しいものComparatorを作成するだけで完了です。

異なる型のインスタンスを並べ替えるを書くのも簡単です -関係するすべてのインスタンスがお互いを知る必要があるため、これComparatorは難しいです.などComparablecompareTo()

于 2012-12-04T17:04:15.370 に答える
0

java.util.Collections javadocs のクイック スキャンは、これを提供します。

public static void sort(List list) - 指定されたリストをその要素の自然な順序に従って昇順に並べ替えます。リスト内のすべての要素は Comparable インターフェイスを実装する必要があります。さらに、リスト内のすべての要素は相互に比較可能でなければなりません (つまり、e1.compareTo(e2) は、リスト内の要素 e1 および e2 に対して ClassCastException をスローしてはなりません)。

public static void sort(List list, Comparator c) - 指定されたコンパレータによって誘導された順序に従って、指定されたリストを並べ替えます。リスト内のすべての要素は、指定されたコンパレータを使用して相互に比較可能でなければなりません(つまり、c.compare(e1, e2) は、リスト内の要素 e1 および e2 に対して ClassCastException をスローしてはなりません)。

sort(List list)Comparable インターフェイスをsort(List list, Comparator c)使用し、コンパレータを使用すると推測できます。

最後の質問に答えるために、説明した方法で2つのメソッドを使用することに違いはありません... 2つのメソッドを使用する目的は、異なる実装を使用して同じ方法ではなく、異なる方法でオブジェクトを比較できるようにすることです。

于 2012-12-04T16:53:07.217 に答える