Voici un échantillon réel. Notez que Stringimplémente également Comparable.
classAuthorimplementsComparable<Author>{String firstName;String lastName;@Overridepublicint compareTo(Author other){// compareTo should return < 0 if this is supposed to be// less than other, > 0 if this is supposed to be greater than // other and 0 if they are supposed to be equalint last =this.lastName.compareTo(other.lastName);return last ==0?this.firstName.compareTo(other.firstName): last;}}
plus tard..
/**
* List the authors. Sort them by name so it will look good.
*/publicList<Author> listAuthors(){List<Author> authors = readAuthorsFromFileOrSomething();Collections.sort(authors);return authors;}/**
* List unique authors. Sort them by name so it will look good.
*/publicSortedSet<Author> listUniqueAuthors(){List<Author> authors = readAuthorsFromFileOrSomething();returnnewTreeSet<Author>(authors);}
Je veux juste noter que vous voudrez souvent remplacer equals(et donc hashCode) être cohérent avec votre compareTométhode. Par exemple, cela est nécessaire si vous voulez que la classe joue bien avec un TreeSet.
pidge
Pourquoi ne pas simplement revenir last?
Anirban Nag 'tintinmj'
@ AnirbanNag'tintinmj 'pour trier automatiquement par prénom au cas où le nom de famille serait le même.
OddDev
Plus un pour la bonne explication de la raison pour laquelle compareTo renvoie un int et ce que cela signifie. Le plus utile.
james.garriss
1
@ user3932000: C'est vrai, c'est à peu près le but de toutes les interfaces. Mais notez que les "autres méthodes Java" incluent les méthodes écrites par l'utilisateur! En fait, je dirais que la majorité des interfaces sont consommées par le code de l'utilisateur. Dans les bases de code plus grandes, "vous-même" devient rapidement "les autres"
Enno Shioji
40
Comparable définit un ordre naturel. Cela signifie que vous le définissez quand un objet doit être considéré comme "inférieur à" ou "supérieur à".
Supposons que vous ayez un tas d'entiers et que vous vouliez les trier. C'est assez facile, mettez-les simplement dans une collection triée, non?
TreeSet<Integer> m =newTreeSet<Integer>();
m.add(1);
m.add(3);
m.add(2);for(Integer i : m)...// values will be sorted
Mais maintenant supposons que j'ai un objet personnalisé, où le tri a un sens pour moi, mais n'est pas défini. Disons que j'ai des données représentant les districts par code postal avec la densité de population, et je veux les trier par densité:
Maintenant, le moyen le plus simple de les trier est de les définir avec un ordre naturel en implémentant Comparable, ce qui signifie qu'il existe une manière standard de définir ces objets pour être ordonnés:
Notez que vous pouvez faire l'équivalent en définissant un comparateur. La différence est que le comparateur définit la logique de commande en dehors de l'objet . Peut-être que dans un processus séparé, j'ai besoin de commander les mêmes objets par code postal - dans ce cas, l'ordre n'est pas nécessairement une propriété de l'objet, ou diffère de l'ordre naturel des objets. Vous pouvez utiliser un comparateur externe pour définir un ordre personnalisé sur les entiers, par exemple en les triant par leur valeur alphabétique.
Fondamentalement, la logique de commande doit exister quelque part. Cela peut être -
dans l'objet lui-même, s'il est naturellement comparable (étend les entiers comparables -eg)
fourni dans un comparateur externe, comme dans l'exemple ci-dessus.
bon exemple, mais il doit être à la TreeSet<Integer>place de TreeMap<Integer>, car ce dernier n'existe pas, les TreeMaps sont toujours des <Key,Value>paires. Btw, une hypothétique TreeMap<District, Object>ne fonctionnerait que si le district mettait en œuvre Comparable, non? J'essaie toujours de comprendre cela
phil294
14
Cité du javadoc;
Cette interface impose un ordre total sur les objets de chaque classe qui l'implémente. Cet ordre est appelé ordre naturel de la classe, et la méthode compareTo de la classe est appelée sa méthode de comparaison naturelle.
Les listes (et tableaux) d'objets qui implémentent cette interface peuvent être triés automatiquement par Collections.sort (et Arrays.sort). Les objets qui implémentent cette interface peuvent être utilisés comme clés dans une carte triée ou comme éléments dans un ensemble trié, sans qu'il soit nécessaire de spécifier un comparateur.
Je dirais que la phrase après celle que vous avez mise en gras est tout aussi importante (sinon plus).
Michael Borgwardt
8
Le fait qu'une classe implémente Comparablesignifie que vous pouvez prendre deux objets de cette classe et les comparer. Certaines classes, comme certaines collections (fonction de tri dans une collection) qui maintiennent les objets dans l'ordre, reposent sur leur comparaison (pour trier, vous devez savoir quel objet est le «plus gros» et ainsi de suite).
La plupart des exemples ci-dessus montrent comment réutiliser un objet comparable existant dans la fonction compareTo. Si vous souhaitez implémenter votre propre compareTo lorsque vous souhaitez comparer deux objets de la même classe, dites un objet AirlineTicket que vous souhaitez trier par prix (moins est classé en premier), suivi du nombre d'escales (encore une fois, moins est classé premier), vous feriez ce qui suit:
classAirlineTicketimplementsComparable<Cost>{publicdouble cost;publicint stopovers;publicAirlineTicket(double cost,int stopovers){this.cost = cost;this.stopovers = stopovers ;}publicint compareTo(Cost o){if(this.cost != o.cost)returnDouble.compare(this.cost, o.cost);//sorting in ascending order. if(this.stopovers != o.stopovers)returnthis.stopovers - o.stopovers;//again, ascending but swap the two if you want descendingreturn0;}}
Ce que Fernando veut dire, c'est: si vous stockez des "choses" qui implémentent Comparable dans une classe de conteneur triée, la classe de conteneur triée peut automatiquement ordonner ces "choses".
Ian Durkan
2
Comparable est utilisé pour comparer les instances de votre classe. Nous pouvons comparer des instances de plusieurs façons, c'est pourquoi nous devons implémenter une méthode compareToafin de savoir comment (attributs) nous voulons comparer les instances.
Dog classe:
package test;import java.util.Arrays;publicclassMain{publicstaticvoid main(String[] args){Dog d1 =newDog("brutus");Dog d2 =newDog("medor");Dog d3 =newDog("ara");Dog[] dogs =newDog[3];
dogs[0]= d1;
dogs[1]= d2;
dogs[2]= d3;for(int i =0; i <3; i++){System.out.println(dogs[i].getName());}/**
* Output:
* brutus
* medor
* ara
*/Arrays.sort(dogs,Dog.NameComparator);for(int i =0; i <3; i++){System.out.println(dogs[i].getName());}/**
* Output:
* ara
* medor
* brutus
*/}}
Main classe:
package test;import java.util.Arrays;publicclassMain{publicstaticvoid main(String[] args){Dog d1 =newDog("brutus");Dog d2 =newDog("medor");Dog d3 =newDog("ara");Dog[] dogs =newDog[3];
dogs[0]= d1;
dogs[1]= d2;
dogs[2]= d3;for(int i =0; i <3; i++){System.out.println(dogs[i].getName());}/**
* Output:
* brutus
* medor
* ara
*/Arrays.sort(dogs,Dog.NameComparator);for(int i =0; i <3; i++){System.out.println(dogs[i].getName());}/**
* Output:
* ara
* medor
* brutus
*/}}
Voici un bon exemple comment utiliser comparable en Java:
Lorsque vous implémentez l' Comparableinterface, vous devez implémenter la méthode compareTo(). Vous en avez besoin pour comparer des objets, afin d'utiliser, par exemple, la méthode de tri de ArrayListclasse. Vous avez besoin d'un moyen de comparer vos objets pour pouvoir les trier. Vous avez donc besoin d'une compareTo()méthode personnalisée dans votre classe pour pouvoir l'utiliser avec la ArrayListméthode sort. La compareTo()méthode renvoie -1,0,1.
Je viens de lire un chapitre correspondant dans Java Head 2.0, j'apprends encore.
OK, mais pourquoi ne pas simplement définir une compareTo()méthode sans implémenter une interface comparable. Par exemple, une classe Citydéfinie par ses nameet temperatureet
Réponses:
Voici un échantillon réel. Notez que
String
implémente égalementComparable
.plus tard..
la source
equals
(et donchashCode
) être cohérent avec votrecompareTo
méthode. Par exemple, cela est nécessaire si vous voulez que la classe joue bien avec unTreeSet
.last
?Comparable définit un ordre naturel. Cela signifie que vous le définissez quand un objet doit être considéré comme "inférieur à" ou "supérieur à".
Supposons que vous ayez un tas d'entiers et que vous vouliez les trier. C'est assez facile, mettez-les simplement dans une collection triée, non?
Mais maintenant supposons que j'ai un objet personnalisé, où le tri a un sens pour moi, mais n'est pas défini. Disons que j'ai des données représentant les districts par code postal avec la densité de population, et je veux les trier par densité:
Maintenant, le moyen le plus simple de les trier est de les définir avec un ordre naturel en implémentant Comparable, ce qui signifie qu'il existe une manière standard de définir ces objets pour être ordonnés:
Notez que vous pouvez faire l'équivalent en définissant un comparateur. La différence est que le comparateur définit la logique de commande en dehors de l'objet . Peut-être que dans un processus séparé, j'ai besoin de commander les mêmes objets par code postal - dans ce cas, l'ordre n'est pas nécessairement une propriété de l'objet, ou diffère de l'ordre naturel des objets. Vous pouvez utiliser un comparateur externe pour définir un ordre personnalisé sur les entiers, par exemple en les triant par leur valeur alphabétique.
Fondamentalement, la logique de commande doit exister quelque part. Cela peut être -
dans l'objet lui-même, s'il est naturellement comparable (étend les entiers comparables -eg)
fourni dans un comparateur externe, comme dans l'exemple ci-dessus.
la source
TreeSet<Integer>
place deTreeMap<Integer>
, car ce dernier n'existe pas, les TreeMaps sont toujours des<Key,Value>
paires. Btw, une hypothétiqueTreeMap<District, Object>
ne fonctionnerait que si le district mettait en œuvre Comparable, non? J'essaie toujours de comprendre celaCité du javadoc;
Edit: ..et a rendu le bit important en gras.
la source
Le fait qu'une classe implémente
Comparable
signifie que vous pouvez prendre deux objets de cette classe et les comparer. Certaines classes, comme certaines collections (fonction de tri dans une collection) qui maintiennent les objets dans l'ordre, reposent sur leur comparaison (pour trier, vous devez savoir quel objet est le «plus gros» et ainsi de suite).la source
La plupart des exemples ci-dessus montrent comment réutiliser un objet comparable existant dans la fonction compareTo. Si vous souhaitez implémenter votre propre compareTo lorsque vous souhaitez comparer deux objets de la même classe, dites un objet AirlineTicket que vous souhaitez trier par prix (moins est classé en premier), suivi du nombre d'escales (encore une fois, moins est classé premier), vous feriez ce qui suit:
la source
Un moyen simple d'implémenter des comparaisons de champs multiples est d' utiliser ComparisonChain de Guava - alors vous pouvez dire
au lieu de
la source
Par exemple, lorsque vous souhaitez avoir une collection ou une carte triée
la source
Comparable est utilisé pour comparer les instances de votre classe. Nous pouvons comparer des instances de plusieurs façons, c'est pourquoi nous devons implémenter une méthode
compareTo
afin de savoir comment (attributs) nous voulons comparer les instances.Dog
classe:Main
classe:Voici un bon exemple comment utiliser comparable en Java:
http://www.onjava.com/pub/a/onjava/2003/03/12/java_comp.html?page=2
la source
Lorsque vous implémentez l'
Comparable
interface, vous devez implémenter la méthodecompareTo()
. Vous en avez besoin pour comparer des objets, afin d'utiliser, par exemple, la méthode de tri deArrayList
classe. Vous avez besoin d'un moyen de comparer vos objets pour pouvoir les trier. Vous avez donc besoin d'unecompareTo()
méthode personnalisée dans votre classe pour pouvoir l'utiliser avec laArrayList
méthode sort. LacompareTo()
méthode renvoie -1,0,1.Je viens de lire un chapitre correspondant dans Java Head 2.0, j'apprends encore.
la source
OK, mais pourquoi ne pas simplement définir une
compareTo()
méthode sans implémenter une interface comparable. Par exemple, une classeCity
définie par sesname
ettemperature
etla source