Quelle est la différence entre compare () et compareTo ()?

110

Quelle est la différence entre Java compare()etcompareTo() méthodes? Ces méthodes donnent-elles la même réponse?

Pops
la source
1
De quelle méthode de comparaison de classe parlez-vous?
Markus Lausberg
pour une explication détaillée des utilisations de compare () et compareTo (): sysdotoutdotprint.com/index.php/2017/03/28/…
mel3kings

Réponses:

160

De JavaNotes :

  • a.compareTo(b):
    Interface comparable: compare les valeurs et renvoie un entier qui indique si les valeurs sont inférieures, égales ou supérieures à.
    Si vos objets de classe ont un ordre naturel , implémentez l' Comparable<T>interface et définissez cette méthode. Toutes les classes Java qui ont un ordre naturel de mettre en œuvre Comparable<T>- Exemple: String, les classes wrapper ,BigInteger

  • compare(a, b):
    Interface de comparaison: compare les valeurs de deux objets. Ceci est implémenté dans le cadre de l' Comparator<T>interface, et l' utilisation typique est de définir une ou plusieurs petites classes d'utilité qui implémentent ceci, pour passer à des méthodes telles que sort()ou pour une utilisation en triant des structures de données telles que TreeMapetTreeSet . Vous souhaiterez peut-être créer un objet Comparator pour les éléments suivants:

    • Comparaisons multiples . Pour fournir plusieurs façons différentes de trier quelque chose. Par exemple, vous voudrez peut-être trier une classe Person par nom, ID, âge, hauteur, ... Vous définiriez un comparateur pour chacun d'entre eux à transmettre à la sort()méthode.
    • Classe système Pour fournir des méthodes de comparaison pour les classes sur lesquelles vous n'avez aucun contrôle. Par exemple, vous pouvez définir un comparateur pour les chaînes qui les compare par longueur.
    • Modèle de stratégie Pour implémenter un modèle de stratégie, qui est une situation où vous souhaitez représenter un algorithme comme un objet que vous pouvez passer en paramètre, enregistrer dans une structure de données, etc.

Si vos objets de classe ont un ordre de tri naturel, vous n'aurez peut-être pas besoin de compare ().


Résumé de http://www.digizol.com/2008/07/java-sorting-comparator-vs-comparable.html

Comparable
Un objet comparable est capable de se comparer à un autre objet.

Comparateur
Un objet comparateur est capable de comparer deux objets différents. La classe ne compare pas ses instances, mais certaines autres instances de la classe.


Contextes de cas d'utilisation:

Interface comparable

La méthode equals ==et les != opérateurs et testent l'égalité / l'inégalité, mais ne fournissent pas de moyen de tester les valeurs relatives .
Certaines classes (par exemple, String et d'autres classes avec un ordre naturel) implémentent l' Comparable<T>interface, qui définit une compareTo()méthode.
Vous souhaiterez l'implémenter Comparable<T>dans votre classe si vous souhaitez l'utiliser avec des méthodes Collections.sort()ou Arrays.sort().

Définition d'un objet Comparator

Vous pouvez créer des comparateurs pour trier n'importe quelle manière arbitraire pour n'importe quelle classe .
Par exemple, la Stringclasse définit le CASE_INSENSITIVE_ORDERcomparateur .


La différence entre les deux approches peut être liée à la notion de:
Collection ordonnée :

Lorsqu'une collection est ordonnée, cela signifie que vous pouvez itérer dans la collection dans un ordre spécifique (non aléatoire) (a Hashtablen'est pas ordonné).

Une collection avec un ordre naturel n'est pas seulement ordonnée, mais triée . Définir un ordre naturel peut être difficile! (comme dans l'ordre de chaîne naturel ).


Autre différence, soulignée par HaveAGuess dans les commentaires :

  • Comparable est dans l'implémentation et n'est pas visible depuis l'interface, donc lorsque vous triez, vous ne savez pas vraiment ce qui va se passer.
  • Comparator vous donne l'assurance que la commande sera bien définie.
VonC
la source
2
Puisque cette réponse est exhaustive, voici quelque chose qui m'ennuie à propos de Comparable que vous aimeriez ajouter: c'est dans l'implémentation et non visible depuis l'interface, donc lorsque vous triez, vous ne savez pas vraiment ce qui va se passer. L'utilisation d'un comparateur vous donne l'assurance que la commande sera bien définie
HaveAGuess
@HaveAGuess bon point. J'ai inclus votre commentaire dans la réponse pour plus de visibilité.
VonC
les objets ont un ordre naturel, que signifie ici l'ordre naturel? Un membre de données de chaîne pour par exemple le nom dans la classe d'employé a-t-il un ordre naturel?
Narendra Jaggi
@NarendraJaggi Voir en.wikipedia.org/wiki/Enumeration . Un ordre qui facilite le dénombrement. "Naturel" dans le sens où un ordre bien donné sur l'ensemble d'index fournit un moyen unique de lister l'élément suivant étant donné une énumération partielle
VonC
2
@VedantKekan Merci. J'ai restauré 2 liens dans cette réponse.
VonC
16

compareTo()provient de l' Comparableinterface.

compare()provient de l' Comparatorinterface.

Les deux méthodes font la même chose, mais chaque interface est utilisée dans un contexte légèrement différent.

L' interface Comparable est utilisée pour imposer un ordre naturel aux objets de la classe d'implémentation. La compareTo()méthode s'appelle la méthode de comparaison naturelle. L' interface Comparator est utilisée pour imposer un ordre total aux objets de la classe d'implémentation. Pour plus d'informations, consultez les liens pour savoir exactement quand utiliser chaque interface.

Yuval Adam
la source
pouvez-vous donner quelques exemples? Les deux méthodes donnent les mêmes réponses?
Je ne sais pas pourquoi «Comparable» est pour l'ordre naturel? Nous pouvons le personnaliser, n'est-ce pas?
c-an
14

Similitudes: les
deux sont des moyens personnalisés de comparer deux objets.
Les deux renvoient un intdécrivant la relation entre deux objets.

Différences: La méthode compare()est une méthode que vous êtes obligé de mettre en œuvre si vous implémentez l' Comparatorinterface. Il vous permet de passer deux objets dans la méthode et il renvoie une intdescription de leur relation.

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

La méthode compareTo()est une méthode que vous êtes obligé de mettre en œuvre si vous implémentez l' Comparableinterface. Il permet de comparer un objet à des objets de type similaire.

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

Résumé:
Fondamentalement, ce sont deux façons différentes de comparer les choses.

jjnguy
la source
9

Les méthodes ne doivent pas nécessairement donner les mêmes réponses. Cela dépend des objets / classes que vous les appelez.

Si vous implémentez vos propres classes que vous savez que vous souhaitez comparer à un certain stade, vous pouvez leur demander d'implémenter l'interface Comparable et d'implémenter la méthode compareTo () en conséquence.

Si vous utilisez certaines classes d'une API qui n'implémentent pas l'interface Comparable, mais que vous souhaitez quand même les comparer. Ie pour le tri. Vous pouvez créer votre propre classe qui implémente l'interface Comparator et dans sa méthode compare () vous implémentez la logique.

Nicolai
la source
3

L' interface comparable contient une méthode appelée compareTo(obj)qui ne prend qu'un seul argument et se compare à une autre instance ou à des objets de la même classe.

L' interface de comparaison contient une méthode appelée compare(obj1,obj2)qui prend deux arguments et compare la valeur de deux objets de la même classe ou de classes différentes.

dilip kumar
la source
3
compareTo(T object)

provient de l'interface java.lang.Comparable, implémentée pour comparer cet objet avec un autre afin de donner une valeur int négative pour cet objet étant inférieure à, 0 pour égal, ou une valeur positive pour supérieure à l'autre. C'est la méthode de comparaison la plus pratique, mais elle doit être implémentée dans chaque classe que vous souhaitez comparer.

compare(T obj1, T obj2)

provient de l'interface java.util.Comparator, implémentée dans une classe distincte qui compare les objets d'une autre classe pour donner une valeur int négative pour le premier objet étant inférieure à, 0 pour égal, ou une valeur positive pour supérieure au deuxième objet. Elle est nécessaire lorsque vous ne pouvez pas faire en sorte qu'une classe implémente compareTo () car elle n'est pas modifiable. Il est également utilisé lorsque vous souhaitez comparer des objets de différentes manières, pas une seule (par exemple par nom ou par âge).

godlovesdavid
la source
3

En utilisant Comparator, nous pouvons avoir n nombre de logique de comparaison écrite pour une classe .

Par exemple

Pour une classe de voiture

Nous pouvons avoir une classe de comparateur à comparer en fonction du numéro de modèle de la voiture. Nous pouvons également avoir une classe de comparaison à comparer en fonction de l'année modèle de la voiture.

Classe de voiture

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;
    }

}

Comparateur n ° 1 basé sur le numéro de modèle

public class CarModelNoCompartor implements Comparator<Car>{

    public int compare(Car o1, Car o2) {

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

}

Comparateur n ° 2 basé sur l'année modèle

public class CarModelYearComparator implements Comparator<Car> {

    public int compare(Car o1, Car o2) {

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

}

Mais ce n'est pas possible avec le cas de l' interface Comparable .

En cas d'interface Comparable, nous ne pouvons avoir qu'une seule logique dans la méthode compareTo () .

IamVickyAV
la source
2

La relation de l'objet ayant cette méthode et de ses collaborateurs est différente.

compareTo()est une méthode de l'interface Comparable , elle est donc utilisée pour comparer cette instance à une autre.

compare()est une méthode de l'interface Comparator , elle est donc utilisée pour comparer deux instances différentes d'une autre classe entre elles.

Si vous voulez, l'implémentation Comparablesignifie que les instances de la classe peuvent être facilement comparées.
La mise en œuvre Comparatorsignifie que les instances sont adaptées pour comparer différents objets (d'autres classes).

Ole
la source
2

La principale différence réside dans l'utilisation des interfaces:

Comparable (qui a compareTo ()) nécessite que les objets soient comparés (afin d'utiliser un TreeMap, ou pour trier une liste) pour implémenter cette interface. Mais que se passe-t-il si la classe n'implémente pas Comparable et que vous ne pouvez pas la modifier car elle fait partie d'une bibliothèque tierce? Ensuite, vous devez implémenter un comparateur, ce qui est un peu moins pratique à utiliser.

Michael Borgwardt
la source
2

compareTo()est appelé sur un objet, pour le comparer à un autre objet. compare()est appelé sur un objet pour comparer deux autres objets.

La différence est là où la logique qui effectue la comparaison réelle est définie.

Abgan
la source
Ce n'est pas ce que j'appellerais une réponse fantastique, mais je ne pense pas qu'elle mérite un vote défavorable.
Paul Tomblin
D'accord, je réserve personnellement les votes négatifs pour les réponses erronées ou trompeuses. Celui-ci est définitivement correct.
Joachim Sauer
Alors, où sont ces gens «sympathiques» qui m'ont critiqué? C'est ma deuxième bonne réponse qui a été rejetée parce que quelqu'un a raté le point. Soit le point de vote défavorable, soit le point de ma réponse. La vie est si cruelle .. ;-)
Abgan
0

Lorsque vous souhaitez trier une liste qui inclut l'objet Foo, la classe Foo doit implémenter l'interface Comparable, car la méthode de tri de la liste utilise cette méthode.

Lorsque vous souhaitez écrire une classe Util qui compare deux autres classes, vous pouvez implémenter la classe Comparator.

Markus Lausberg
la source
0


Nom de la table des employés , DoB, Salary
Tomas, 2/10/1982, 300
Daniel, 3/11/1990, 400
Kwame, 2/10/1998, 520

L' interface Comparable vous permet de trier une liste d'objets, par exemple Employés en référence à un champ principal - par exemple, vous pouvez trier par nom ou par salaire avec la méthode CompareTo ()

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

Une interface plus flexible pour de telles exigences est fournie par l' interface Comparator , dont la seule méthode est compare ()

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

Exemple de code

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
la source
0

Encore un point:

  • compareTo()provient de l' Comparableinterface et compare()provient de l' Comparatorinterface.
  • Comparableest utilisé pour définir un ordre par défaut pour les objets dans une classe tandis que Comparatorest utilisé pour définir un ordre personnalisé à passer à une méthode.
Premraj
la source
0

Il y a un aspect technique qui mérite également d'être souligné. Supposons que vous ayez besoin d'un paramétrage du comportement de comparaison à partir d'une classe cliente et que vous vous demandez s'il faut utiliser Comparableou Comparatorpour une méthode comme celle-ci:

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");
        }
    }
}

comparableserait un lambda ou un objet, et il n'y a aucun moyen comparabled'accéder aux champs de thisPokemon. (Dans un lambda, thisfait référence à l'instance de classe externe dans la portée du lambda, telle que définie dans le texte du programme.) Donc, cela ne vole pas , et nous devons utiliser a Comparatoravec deux arguments.

flow2k
la source
0

Utilisez l'interface Comparable pour trier sur la base de plus d'une valeur comme l'âge, le nom, le dept_name ... Pour une valeur, utilisez l'interface Comparator

G.Brown
la source
-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);
}

Ici, dans return obj1.compareTo(obj1)ou return obj1.compareTo(obj)instruction, ne prenez que Object; primitive n'est pas autorisée. Par exemple

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

Mais

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

nom est String Object donc cela a fonctionné. Si vous souhaitez trier le numéro de rouleau d'étudiant, utilisez le code ci-dessous.

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

ou

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
la source