Quand une classe doit-elle être comparable et / ou comparative?

138

J'ai vu des classes qui implémentent à la fois Comparable et Comparator . Qu'est-ce que ça veut dire? Pourquoi utiliserais-je l'un plutôt que l'autre?

Nick Heiner
la source
18
Avez-vous lu le javadoc sur eux? Il décrit les différents très clairement.
skaffman le
1
Qu'est-ce qui est comparable et comparateur et quand utiliser comparable et comparateur. Pour les connaître, lisez ce lien. cela vous aidera à comprendre leur comportement et leur utilisation. http://iandjava.blogspot.in/2012/10/comparable-and-comparator.html
RockStar
6
C'est une bonne question avec une bonne réponse objective. Je suis consterné qu'il soit fermé.
Russell Silva
3
D'autres questions sur StackOverflow font référence à cela comme la question définitive «Quelle est la différence entre un comparateur et un comparable». Pourquoi est-il marqué comme «non constructif»? En tant que débutant en Java, c'était une question très utile!
Pete

Réponses:

241

Le texte ci-dessous provient de Comparator vs Comparable

Comparable

Un objet comparable est capable de se comparer à un autre objet. La classe elle-même doit implémenter l' java.lang.Comparableinterface afin de pouvoir comparer ses instances.

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. Cette classe de comparateur doit implémenter l' java.util.Comparatorinterface.

Dan
la source
pour une explication détaillée des utilisations de Comparator et de comparable: sysdotoutdotprint.com/index.php/2017/03/28/…
mel3kings
2
Un autre bon article: codecramp.com/java-comparable-vs-comparator
EMM
@ mel3kings - Le lien n'est plus accessible.
Gaurav
152

Implémentation Comparablesignifie « Je peux me comparer à un autre objet » . Ceci est généralement utile lorsqu'il existe une seule comparaison naturelle par défaut.

Implémenter Comparatorsignifie " Je peux comparer deux autres objets. " Ceci est généralement utile lorsqu'il existe plusieurs façons de comparer deux instances d'un type - par exemple, vous pouvez comparer des personnes par âge, nom, etc.

Jon Skeet
la source
1
Bonjour skeet, pouvez-vous s'il vous plaît déposer le code en utilisant comparable et comparateur.
Mdhar9e
5
@ mdhar9e: Il y a beaucoup d'exemples autour - si vous avez du mal à les traduire dans votre scénario spécifique, veuillez donner plus d'informations dans une nouvelle question.
Jon Skeet
2
@alireza: J'ai déjà donné un exemple dans le deuxième paragraphe: en ayant différents comparateurs, vous pouvez trier la même collection (personnes) par différentes propriétés (âge, nom, etc.). Vous ne pouvez pas faire cela simplement en créant un Personoutil Comparable, car vous ne pouvez pas changer la façon dont deux personnes sont comparées.
Jon Skeet
1
@feelgoodandprogramming: Non, ce sont des algorithmes de tri différents . Il y a potentiellement trois morceaux de code ici, dans trois classes différentes: 1) L'entité elle-même, par exemple Person. 2) Le comparateur, par exemple PersonAgeComparatorqui est capable de comparer deux entités différentes et de décider laquelle doit venir en premier dans cet ordre de tri particulier. 3) Le code de tri, qui prend une collection d'entités et un comparateur, et trie cette collection à l'aide du comparateur pour déterminer l'ordre.
Jon Skeet
2
@RishiKeshPathak: Eh bien, c'est plus que vous utilisez Comparable s'il n'y a qu'une seule chose évidente à comparer. Et même dans ce cas, vous pouvez simplement écrire un comparateur. Si vous avez deux programmes différents utilisant la même classe, et que l'un veut trier par âge juste et l'autre par nom, au moins l' un d'entre eux devra utiliser un comparateur.
Jon Skeet
38

Comparable permet à une classe d'implémenter sa propre comparaison:

  • c'est dans la même classe (c'est souvent un avantage)
  • il ne peut y avoir qu'une seule implémentation (vous ne pouvez donc pas l'utiliser si vous voulez deux cas différents)

Par comparaison, Comparator est une comparaison externe:

  • il se trouve généralement dans une instance unique (dans la même classe ou à un autre endroit)
  • vous nommez chaque implémentation avec la façon dont vous voulez trier les choses
  • vous pouvez fournir des comparateurs pour les classes que vous ne contrôlez pas
  • l'implémentation est utilisable même si le premier objet est nul

Dans les deux implémentations, vous pouvez toujours choisir ce que vous voulez comparer . Avec les génériques, vous pouvez le déclarer et le faire vérifier au moment de la compilation. Cela améliore la sécurité, mais il est également difficile de déterminer la valeur appropriée.

À titre indicatif, j'utilise généralement la classe ou l'interface la plus générale à laquelle cet objet pourrait être comparé, dans tous les cas d'utilisation que j'envisage ... Une définition pas très précise cependant! :-(

  • Comparable<Object>vous permet de l'utiliser dans tous les codes au moment de la compilation (ce qui est bon si nécessaire, ou mauvais sinon et vous perdez l'erreur de compilation); votre implémentation doit faire face aux objets et effectuer un cast selon les besoins, mais de manière robuste.
  • Comparable<Itself> est très strict au contraire.

C'est drôle, quand vous vous sous-classez à Subclass, Subclass doit également être comparable et robuste à ce sujet (ou cela briserait le principe de Liskov et vous donnerait des erreurs d'exécution).

KLE
la source
20

java.lang.Comparable

  1. Pour implémenter l' Comparableinterface, la classe doit implémenter une seule méthodecompareTo()

    int a.compareTo(b)

  2. Vous devez modifier la classe dont vous souhaitez trier l'instance. Ainsi, une seule séquence de tri peut être créée par classe.

java.util.Comparator

  1. Pour implémenter l'interface Comparator, la classe doit implémenter une seule méthode compare()

    int compare (a,b)

  2. Vous créez une classe distincte de la classe dont vous souhaitez trier l'instance. Ainsi, plusieurs séquences de tri peuvent être créées par classe.
codiacTushki
la source
14

Comparable sert à fournir un ordre par défaut sur les objets de données, par exemple si les objets de données ont un ordre naturel.

A Comparatorreprésente la commande elle-même pour une utilisation spécifique.

starblue
la source
8

Comparableest généralement préféré. Mais parfois, une classe implémente déjà Comparable, mais vous voulez trier sur une propriété différente. Ensuite, vous êtes obligé d'utiliser unComparator .

Certaines classes prévoient en fait Comparatorsdes cas courants; par exemple, les Strings sont par défaut sensibles à la casse lorsqu'ils sont triés, mais il y a aussi un statique Comparatorappelé CASE_INSENSITIVE_ORDER.

Michael Myers
la source
7
Je ne suis pas sûr d'être d'accord avec le fait que Comparable soit préféré. Certains objets ont un sens aigu de l'ordre naturel - à savoir les nombres, sous toutes leurs formes: nombres naturels, nombres réels, dates, etc. Mais même d'autres objets relativement primitifs comme les chaînes de caractères n'ont pas d'ordre universellement applicable. Dans le cas d'objets plus complexes comme une entité d'un modèle de domaine d'application, l'implémentation de Comparable est généralement une erreur. Leurs nombreuses propriétés font qu'il est trop difficile d'anticiper quelle commande sera demandée le plus souvent.
erickson le
6

voici quelques différences entre Comparator et Comparable que j'ai trouvées sur le Web:

  1. Si vous voyez alors la différence logique entre ces deux est Comparator en Java, comparez deux objets qui lui sont fournis, tandis que l'interface Comparable compare "cette" référence à l'objet spécifié.

  2. Comparable en Java est utilisé pour implémenter l'ordre naturel des objets. Dans les classes API Java String, Date et wrapper implémentent l'interface Comparable.

  3. Si une classe implémente une interface Comparable en Java, la collection de cet objet List ou Array peut être triée automatiquement à l'aide de la méthode Collections.sort () ou Array.sort () et l'objet sera trié en fonction de l'ordre naturel défini par la méthode CompareTo.

  4. Les objets qui implémentent Comparable en Java peuvent être utilisés comme clés dans une carte triée ou des éléments dans un ensemble trié, par exemple TreeSet, sans spécifier de comparateur.

site: Comment utiliser Comparator et Comparable en Java? Avec exemple

Lire la suite: Comment utiliser Comparator et Comparable en Java? Avec exemple

javapassion
la source
5

Comparableest pour les objets avec un ordre naturel. L'objet lui-même sait comment il doit être ordonné.
Comparatorest destiné aux objets sans ordre naturel ou lorsque vous souhaitez utiliser un ordre différent.

Michael Lloyd Lee mlk
la source
4

Différence entre les interfaces de comparaison et de comparaison

Comparable est utilisé pour se comparer en utilisant avec un autre objet.

Comparator est utilisé pour comparer deux types de données sont des objets.

SravaniChowdary.Gorijavolu
la source
2

Si vous voyez alors la différence logique entre ces deux est Comparatoren Java, comparez deux objets qui lui sont fournis, tandis que l' Comparableinterface compare "cette" référence à l'objet spécifié.

Comparableen Java est utilisé pour implémenter l'ordre naturel des objets. Dans les classes API Java String, Date et wrapper implémententComparable interface.

Si une classe implémente une Comparableinterface en Java, alors la collection de cet objet Listou Arraypeut être triée automatiquement à l'aide de la méthode Collections.sort()ou Array.sort()et l'objet sera trié en fonction de son ordre naturel défini parcompareTo méthode.

Les objets qui implémentent Comparableen Java peuvent être utilisés comme clés dans une carte triée ou des éléments dans un ensemble trié par exemple TreeSet, sans en spécifier aucun Comparator.

Srinivas
la source
0

Ma bibliothèque d'annotations pour l'implémentation de Comparable et 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);         
    }  
} 

Cliquez sur le lien pour voir plus d'exemples. compamatique

Jianmin Liu
la source
3
Bienvenue dans stackoverflow. Cette question est ancienne et a déjà reçu une réponse. En règle générale, il est préférable de ne pas ressusciter les threads obsolètes à moins que votre réponse n'apporte quelque chose de significativement nouveau ou différent par rapport aux réponses précédentes.
oers