Was ist der Unterschied zwischen compare () und compareTo ()?

110

Was ist der Unterschied zwischen Java compare()und compareTo()Methoden? Geben diese Methoden die gleiche Antwort?

Pops
quelle
1
Welche Vergleichsklassenmethode meinst du?
Markus Lausberg
Für eine detaillierte Erklärung der Verwendung von compare () und compareTo (): sysdotoutdotprint.com/index.php/2017/03/28/…
mel3kings

Antworten:

160

Aus JavaNotes :

  • a.compareTo(b):
    Vergleichbare Schnittstelle: Vergleicht Werte und gibt ein int zurück, das angibt, ob die Werte kleiner, gleich oder größer als sind.
    Wenn Ihre Klassenobjekte eine natürliche Reihenfolge haben , implementieren Sie die Comparable<T>Schnittstelle und definieren Sie diese Methode. Alle Java-Klassen mit einem natürlichen Ordnungsimplement Comparable<T>- Beispiel : String, Wrapper-Klassen ,BigInteger

  • compare(a, b):
    Komparatorschnittstelle : Vergleicht Werte von zwei Objekten. Dies wird als Teil der Comparator<T>Schnittstelle implementiert, und die typische Verwendung besteht darin, eine oder mehrere kleine Dienstprogrammklassen zu definieren, die dies implementieren, um sie an Methoden wie sort()oder zur Verwendung durch Sortieren von Datenstrukturen wie TreeMapund zu übergebenTreeSet . Möglicherweise möchten Sie ein Comparator-Objekt für Folgendes erstellen:

    • Mehrere Vergleiche . Verschiedene Möglichkeiten zum Sortieren von Objekten. Beispielsweise möchten Sie möglicherweise eine Personenklasse nach Name, ID, Alter, Größe usw. sortieren. Sie definieren einen Komparator für jede dieser Klassen, die an die sort()Methode übergeben werden sollen.
    • Systemklasse Zum Bereitstellen von Vergleichsmethoden für Klassen, über die Sie keine Kontrolle haben. Sie können beispielsweise einen Komparator für Zeichenfolgen definieren, der sie nach Länge vergleicht.
    • Strategiemuster Zum Implementieren eines Strategiemusters. In dieser Situation möchten Sie einen Algorithmus als Objekt darstellen, das Sie als Parameter übergeben, in einer Datenstruktur speichern usw. können.

Wenn Ihre Klassenobjekte eine natürliche Sortierreihenfolge haben, benötigen Sie möglicherweise nicht compare ().


Zusammenfassung von http://www.digizol.com/2008/07/java-sorting-comparator-vs-comparable.html

Vergleichbar
Ein vergleichbares Objekt kann sich mit einem anderen Objekt vergleichen.

Komparator
Ein Komparatorobjekt kann zwei verschiedene Objekte vergleichen. Die Klasse vergleicht nicht ihre Instanzen, sondern die Instanzen einiger anderer Klassen.


Anwendungsfallkontexte:

Vergleichbare Schnittstelle

Die Methode equals und ==und != Operatoren testen auf Gleichheit / Ungleichheit, bieten jedoch keine Möglichkeit zum Testen auf relative Werte .
Einige Klassen (z. B. String und andere Klassen mit einer natürlichen Reihenfolge) implementieren die Comparable<T>Schnittstelle, die eine compareTo()Methode definiert .
Sie möchten Comparable<T>in Ihrer Klasse implementieren, wenn Sie es mit Collections.sort()oder verwenden möchtenArrays.sort() Methoden verwenden .

Komparatorobjekt definieren

Sie können Komparatoren erstellen, um eine beliebige Art und Weise für jede Klasse zu sortieren .
Beispielsweise Stringdefiniert die Klasse den CASE_INSENSITIVE_ORDERKomparator .


Der Unterschied zwischen den beiden Ansätzen kann mit dem Begriff verknüpft werden:
Bestellte Sammlung :

Wenn eine Sammlung bestellt wird, bedeutet dies, dass Sie in der Sammlung in einer bestimmten (nicht zufälligen) Reihenfolge iterieren können (a Hashtable ist nicht bestellt).

Eine Sammlung mit einer natürlichen Reihenfolge wird nicht nur bestellt, sondern sortiert . Eine natürliche Ordnung zu definieren kann schwierig sein! (wie in natürlicher Stringreihenfolge ).


Ein weiterer Unterschied, auf den HaveAGuess in den Kommentaren hingewiesen hat :

  • Comparable befindet sich in der Implementierung und ist von der Benutzeroberfläche aus nicht sichtbar. Wenn Sie also sortieren, wissen Sie nicht wirklich, was passieren wird.
  • Comparator gibt Ihnen die Gewissheit, dass die Bestellung genau definiert ist.
VonC
quelle
2
Da diese Antwort vollständig ist, ärgert mich Folgendes über Comparable, das Sie vielleicht hinzufügen möchten: Sie befindet sich in der Implementierung und ist über die Benutzeroberfläche nicht sichtbar. Wenn Sie also sortieren, wissen Sie nicht wirklich, was passieren wird. Die Verwendung eines Komparators gibt Ihnen die Gewissheit, dass die Reihenfolge genau definiert ist
HaveAGuess
@HaveAGuess guter Punkt. Ich habe Ihren Kommentar zur besseren Sichtbarkeit in die Antwort aufgenommen.
VonC
Objekte haben eine natürliche Ordnung, was bedeutet natürliche Ordnung hier? Hat ein String-Datenelement für zB Name in Mitarbeiterklasse eine natürliche Reihenfolge?
Narendra Jaggi
@NarendraJaggi Siehe en.wikipedia.org/wiki/Enumeration . Eine Reihenfolge, die die Aufzählung erleichtert. "Natürlich" in dem Sinne, dass eine gegebene Ordnung im Indexsatz eine einzigartige Möglichkeit bietet, das nächste Element bei einer
Teilaufzählung aufzulisten
2
@VedantKekan Danke. Ich habe 2 Links in dieser Antwort wiederhergestellt.
VonC
16

compareTo()ist von der ComparableSchnittstelle.

compare()ist von der ComparatorSchnittstelle.

Beide Methoden machen dasselbe, aber jede Schnittstelle wird in einem etwas anderen Kontext verwendet.

Die vergleichbare Schnittstelle wird verwendet, um den Objekten der implementierenden Klasse eine natürliche Reihenfolge aufzuerlegen. Die compareTo()Methode wird als natürliche Vergleichsmethode bezeichnet. Die Comparator- Schnittstelle wird verwendet, um den Objekten der implementierenden Klasse eine Gesamtreihenfolge aufzuerlegen. Weitere Informationen finden Sie unter den Links, um genau zu erfahren, wann die einzelnen Schnittstellen verwendet werden sollen.

Yuval Adam
quelle
Können Sie einige Beispiele nennen? Beide Methoden geben die gleichen Antworten?
Ich weiß nicht, warum 'Vergleichbar' für natürliche Ordnung ist? Wir können es anpassen, nicht wahr?
c-an
14

Ähnlichkeiten:
Beide sind benutzerdefinierte Methoden zum Vergleichen von zwei Objekten.
Beide geben eine intBeschreibung der Beziehung zwischen zwei Objekten zurück.

Unterschiede: Die Methode compare()ist eine Methode, zu deren Implementierung Sie verpflichtet sind, wenn Sie die ComparatorSchnittstelle implementieren . Sie können zwei Objekte an die Methode übergeben und eine intBeschreibung ihrer Beziehung zurückgeben.

Comparator comp = new MyComparator();
int result = comp.compare(object1, object2);

Die Methode compareTo()ist eine Methode, zu deren Implementierung Sie verpflichtet sind, wenn Sie die ComparableSchnittstelle implementieren . Damit kann ein Objekt mit Objekten ähnlichen Typs verglichen werden.

String s = "hi";
int result = s.compareTo("bye");

Zusammenfassung:
Grundsätzlich gibt es zwei verschiedene Möglichkeiten, Dinge zu vergleichen.

jjnguy
quelle
9

Die Methoden müssen nicht die gleichen Antworten geben. Das hängt davon ab, welche Objekte / Klassen Sie sie nennen.

Wenn Sie Ihre eigenen Klassen implementieren, von denen Sie wissen, dass Sie sie irgendwann vergleichen möchten, können Sie sie die Comparable-Schnittstelle implementieren lassen und die compareTo () -Methode entsprechend implementieren.

Wenn Sie einige Klassen aus einer API verwenden, die die Schnittstelle Comparable nicht implementieren, diese aber dennoch vergleichen möchten. Dh zum Sortieren. Sie können eine eigene Klasse erstellen, die die Comparator-Schnittstelle implementiert, und in ihrer compare () -Methode die Logik implementieren.

Nicolai
quelle
3

Die vergleichbare Schnittstelle enthält eine aufgerufene Methode, compareTo(obj)die nur ein Argument akzeptiert und sich mit einer anderen Instanz oder Objekten derselben Klasse vergleicht.

Die Komparatorschnittstelle enthält eine aufgerufene Methode, compare(obj1,obj2)die zwei Argumente akzeptiert und den Wert von zwei Objekten aus derselben oder verschiedenen Klassen vergleicht.

Dilip Kumar
quelle
3
compareTo(T object)

stammt von der Schnittstelle java.lang.Comparable, die implementiert wurde, um dieses Objekt mit einem anderen zu vergleichen und einen negativen int-Wert für dieses Objekt zu erhalten, der kleiner als, 0 für gleich oder ein positiver Wert für größer als das andere ist. Dies ist die bequemere Vergleichsmethode, muss jedoch in jeder Klasse implementiert werden, die Sie vergleichen möchten.

compare(T obj1, T obj2)

stammt von der Schnittstelle java.util.Comparator, die in einer separaten Klasse implementiert ist, die die Objekte einer anderen Klasse vergleicht, um einen negativen int-Wert für das erste Objekt zu erhalten, der kleiner als, 0 für gleich oder ein positiver Wert für größer als das zweite Objekt ist. Es wird benötigt, wenn eine Klasse compareTo () nicht implementieren kann, da es nicht geändert werden kann. Es wird auch verwendet, wenn Sie verschiedene Methoden zum Vergleichen von Objekten wünschen, nicht nur eines (z. B. nach Name oder Alter).

godlovesdavid
quelle
3

Mit Comparator können wir n Vergleichslogiken für eine Klasse schreiben lassen .

Z.B

Für eine Autoklasse

Wir können eine Vergleichsklasse haben, die basierend auf der Fahrzeugmodellnummer verglichen werden kann. Wir können auch eine Vergleichsklasse haben, die basierend auf dem Modelljahr des Autos verglichen werden kann.

Autoklasse

public class Car  {

    int modelNo;

    int modelYear;

    public int getModelNo() {
        return modelNo;
    }

    public void setModelNo(int modelNo) {
        this.modelNo = modelNo;
    }

    public int getModelYear() {
        return modelYear;
    }

    public void setModelYear(int modelYear) {
        this.modelYear = modelYear;
    }

}

Komparator Nr. 1 basierend auf Modell Nr

public class CarModelNoCompartor implements Comparator<Car>{

    public int compare(Car o1, Car o2) {

        return o1.getModelNo() - o2.getModelNo();
    }

}

Komparator Nr. 2 basierend auf dem Modelljahr

public class CarModelYearComparator implements Comparator<Car> {

    public int compare(Car o1, Car o2) {

        return o1.getModelYear() - o2.getModelYear();
    }

}

Dies ist jedoch bei der vergleichbaren Schnittstelle nicht möglich .

Im Fall einer vergleichbaren Schnittstelle kann die Methode compareTo () nur eine Logik enthalten .

IamVickyAV
quelle
2

Die Beziehung zwischen dem Objekt mit dieser Methode und seinen Mitarbeitern ist unterschiedlich.

compareTo()ist eine Methode der Schnittstelle Comparable , daher wird sie verwendet, um DIESE Instanz mit einer anderen zu vergleichen.

compare()ist eine Methode der Schnittstelle Vergleicher wird es verwendet , so miteinander zwei unterschiedliche Instanzen einer anderen Klasse zu vergleichen.

Wenn Sie so wollen, Comparablebedeutet die Implementierung , dass Instanzen der Klasse leicht verglichen werden können.
Implementieren Comparatorbedeutet, dass Instanzen geeignet sind, verschiedene Objekte (anderer Klassen) zu vergleichen.

Ole
quelle
2

Der Hauptunterschied besteht in der Verwendung der Schnittstellen:

Comparable (mit compareTo ()) erfordert, dass die Objekte verglichen werden (um eine TreeMap zu verwenden oder eine Liste zu sortieren), um diese Schnittstelle zu implementieren. Aber was ist, wenn die Klasse Comparable nicht implementiert und Sie es nicht ändern können, weil es Teil einer Bibliothek eines Drittanbieters ist? Dann müssen Sie einen Komparator implementieren, der etwas weniger bequem zu bedienen ist.

Michael Borgwardt
quelle
2

compareTo()wird für ein Objekt aufgerufen, um es mit einem anderen Objekt zu vergleichen. compare()wird für ein Objekt aufgerufen, um zwei andere Objekte zu vergleichen.

Der Unterschied besteht darin, wo die Logik definiert ist, die den tatsächlichen Vergleich durchführt.

Abgan
quelle
Nicht das, was ich eine fantastische Antwort nennen würde, aber ich denke nicht, dass es eine Ablehnung verdient.
Paul Tomblin
Einverstanden, persönlich behalte ich mir Abstimmungen für falsche oder irreführende Antworten vor. Dieser ist definitiv richtig.
Joachim Sauer
Also, wo sind diese "freundlichen" Leute, die mich herabgestimmt haben? Dies ist meine zweite richtige Antwort, die abgelehnt wurde, weil jemand den Punkt verfehlt hat. Entweder der Punkt der Ablehnung oder der Punkt meiner Antwort. Das Leben ist so grausam .. ;-)
Abgan
0

Wenn Sie eine Liste sortieren möchten, die das Objekt Foo enthält, muss die Foo-Klasse die Schnittstelle Comparable implementieren, da die Sortiermethode der Liste diese Methode verwendet.

Wenn Sie eine Util-Klasse schreiben möchten, die zwei andere Klassen vergleicht, können Sie die Comparator-Klasse implementieren.

Markus Lausberg
quelle
0


Name der Mitarbeitertabelle , DoB, Gehalt
Tomas, 2/10/1982, 300
Daniel, 3/11/1990, 400
Kwame, 10.02.1998, 520

Über die Schnittstelle Vergleichbar können Sie eine Liste von Objekten sortieren, z. B. Mitarbeiter mit Bezug auf ein primäres Feld. Beispielsweise können Sie mit der CompareTo () -Methode nach Namen oder Gehalt sortieren

emp1.getName().compareTo(emp2.getName())

Eine flexiblere Schnittstelle für solche Anforderungen bietet die Comparator- Schnittstelle, deren einzige Methode compare () ist.

public interface Comparator<Employee> {
 int compare(Employee obj1, Employee obj2);
}

Beispielcode

public class NameComparator implements Comparator<Employee> {

public int compare(Employee e1, Employee e2) {
     // some conditions here
        return e1.getName().compareTo(e2.getName()); // returns 1 since (T)omas > (D)an 
    return e1.getSalary().compareTo(e2.getSalary()); // returns -1 since 400 > 300
}

}}

Karto
quelle
0

Noch ein Punkt:

  • compareTo()ist von der ComparableSchnittstelle und compare()ist von der ComparatorSchnittstelle.
  • Comparablewird verwendet, um eine Standardreihenfolge für Objekte innerhalb einer Klasse Comparatorzu definieren, während eine benutzerdefinierte Reihenfolge definiert wird, die an eine Methode übergeben werden soll.
Premraj
quelle
0

Es gibt einen technischen Aspekt, der ebenfalls hervorgehoben werden sollte. Sagen Sie bitte Vergleichsverhalten Parametrisierung von einer Client - Klasse benötigen, und Sie fragen sich, ob zu verwenden Comparableoder , Comparatorwie dies für ein Verfahren:

class Pokemon {
    int healthPoints;
    int attackDamage;
    public void battle (Comparable<Pokemon> comparable, Pokemon opponent) {
        if (comparable.compareTo(opponent) > 0) { //comparable needs to, but cannot, access this.healthPoints for example
            System.out.println("battle won");
        } else {
            System.out.println("battle lost");
        }
    }
}

comparablewäre ein Lambda oder ein Objekt, und es gibt keine Möglichkeit comparable, auf die Felder von thisPokemon zuzugreifen . ( thisBezieht sich in einem Lambda auf die Instanz der äußeren Klasse im Bereich des Lambda, wie im Programmtext definiert.) Das fliegt also nicht , und wir müssen a Comparatormit zwei Argumenten verwenden.

flow2k
quelle
0

Verwenden Sie die vergleichbare Schnittstelle zum Sortieren nach mehr als einem Wert wie Alter, Name, Dept_name ... Verwenden Sie für einen Wert die Vergleichsschnittstelle

G. Brown
quelle
-2
Important Answar
String name;
int roll;

public int compare(Object obj1,Object obj2) { // For Comparator interface
    return obj1.compareTo(obj1);
}

public int compareTo(Object obj1) { // For Comparable Interface
    return obj1.compareTo(obj);
}

Hier in return obj1.compareTo(obj1)oder return obj1.compareTo(obj)Anweisung nur Objekt nehmen; primitiv ist nicht erlaubt. Beispielsweise

name.compareTo(obj1.getName()) // Correct Statement.

Aber

roll.compareTo(obj1.getRoll()) 
// Wrong Statement Compile Time Error Because roll 
// is not an Object Type, it is primitive type.

Name ist String Object, also hat es funktioniert. Wenn Sie die Rollennummer des Schülers sortieren möchten, verwenden Sie den folgenden Code.

public int compareTo(Object obj1) { // For Comparable Interface
    Student s = (Student) obj1;
    return rollno - s.getRollno();
}  

oder

public int compare(Object obj1,Object obj2) { // For Comparator interface
    Student s1 = (Student) obj1;
    Student s2 = (Student) obj2;
    return s1.getRollno() - s2.getRollno();
}  
Bhabani Sankar Sahoo
quelle