Je suis nouveau sur Java et je ne comprends pas vraiment comment utiliser l'interface de comparateur . J'ai un ArrayList
de Item
s dans une classe Inventory
et une classe Item
. Dans la classe Item
, j'ai écrit:
public class Item implements Comparator<Item> {
//stuff
...
@Override
public int compare(Item a, Item b) {
if (a.getID().compareToIgnoreCase(b.getID())>0)
return 1;
else if (a.getID().compareToIgnoreCase(b.getID())<0)
return -1;
else
return 0;
}
}
La méthode getID () donne simplement l'identifiant, que je dois utiliser pour classer par ordre alphabétique les éléments . Je ne sais pas si c'est vrai, cela m'a fait mettre l'annotation @Override
, je ne sais pas pourquoi. Aussi, j'ai écrit une interface qui dit juste:
public interface Comparator<Item>
{
int compare(Item a, Item b);
}
Je ne suis pas sûr de ce bit. De plus, comment implémenter cette méthode pour trier l'arraylist créé dans la classe d'inventaire?
Merci, si ma question n'a pas de sens ou nécessite des éclaircissements, faites le moi savoir.
Pour utiliser l'interface Comparator , vous devez l'implémenter et la transmettre en tant que classe anonyme à Collections.sort (List list, Comparator c) } en tant que second paramètre.
Si vous souhaitez ne transmettre que la liste à Collections.sort (Liste de listes) }, votre classe Item
a alors pour implémenter l'interface Comparable .
Donc, dans les deux cas, les méthodes Collections.sort
savent ordonner les éléments de votre liste
voici un exemple de code:
Classe d'objets implémentant Comparable
+ Inventaire contenant une liste d'éléments
public class Item implements Comparable<Item> {
String id = null;
public Item(String id) {
this.id = id;
}
@Override
public String toString() {
return id;
}
@Override
public int compareTo(Item o) {
return - id.compareToIgnoreCase(o.id);
}
}
public class Inventory {
List<Item> items = new ArrayList<>();
public void addItem(Item item) {
items.add(item);
}
public static void main(String[] args) {
Inventory inventory = new Inventory();
inventory.addItem(new Item("2"));
inventory.addItem(new Item("4"));
inventory.addItem(new Item("1"));
inventory.addItem(new Item("7"));
Collections.sort(inventory.items, new Comparator<Item>() {
@Override
public int compare(Item o1, Item o2) {
return o1.id.compareToIgnoreCase(o2.id);
}
});
System.out.println(inventory.items);
Collections.sort(inventory.items);
System.out.println(inventory.items);
}
}
Sortie
[1, 2, 4, 7] // ascending
[7, 4, 2, 1] // descending since the compareTo method inverts the sign of the comparison result.
EDIT: Tout d’abord, quelques éléments:
@Override
ne devrait pas être obligatoire. Si Eclipse veut que vous le mettiez, ne vous inquiétez pas.import Java.util.Comparator;
tout en haut de votre code (avant le public class
) pour a) utiliser la version fournie par Java et b) rendre votre code compatible avec à peu près tout ce qui existe dans le monde.L'interface de comparateur n'est pas utilisée pour créer une classe pouvant se mettre en ordre. C'est l'interface comparable.
Les deux sont similaires, je vais donc les décrire ici.
Comme vous le savez déjà, l’interface Comparator a une méthode: compare
. Le comparateur est générique (utilise les crochets <>
) et prend le type qu'il comparera à l'intérieur du <>
. Le fait est que les comparateurs sont utilisés pour comparer les éléments de autres classes. Par exemple, je pourrais créer un comparateur pour Java.lang.Integers
qui retourne le contraire de "l'ordre naturel" (comment les entiers sont habituellement commandés).
Les comparateurs servent principalement à donner aux autres objets un moyen de trier leurs paramètres s’ils ne sont pas dans l’ordre naturel. Par exemple, la classe Java.util.TreeSet
prend un comparateur pour sa capacité de tri.
Le but de Comparable est de dire qu'un objet peut être comparé. Il est également générique et prend le type auquel il peut être comparé. Par exemple, un Comparable<String>
peut être comparé à Strings.
Comparable a une méthode: compareTo()
. Contrairement à la fonction compare()
du comparateur, compareTo
prend un paramètre. Cela fonctionne comme compare
, sauf qu'il utilise l'objet invoquant comme un paramètre. Donc, comparableA.compareTo(comparableB)
est identique à comparator.compare(comparableA, comparableB)
.
Comparable établit principalement l'ordre naturel des objets et constitue le moyen par défaut de comparer des objets. Le rôle du comparateur est de remplacer cet ordre naturel lorsque l'on a des besoins différents en matière de comparaison ou de tri des données.
Pour trier une List
, vous pouvez utiliser la méthode déjà disponible: faites défiler jusqu'à sort
dans le Java.util.Collections
classe . Une méthode prend un comparateur, l'autre pas. sort
est statique; utilisez Collections.sort(...)
, pas Collections c = new Collections(); c.sort(...)
. (Collections
n'a même pas de constructeur, alors meh.)
Vous mélangez les interfaces Comparator
et Comparable
.
Comparateur: http://docs.Oracle.com/javase/6/docs/api/Java/util/Comparator.html
Comparable: http://docs.Oracle.com/javase/6/docs/api/Java/lang/Comparable.html
Le rôle de Comparator est une classe (déclarée anonymement sur place ou autrement) pouvant être transférée à une opération nécessitant un ordre et définissant le tri qui sera utilisé sur l'article. Comparator doit être utilisé à l'extérieur de la classe qui doit être triée, s'il existe une autre méthode de tri.
Le but de Comparable est de dire que la classe (qui implémente Comparable) a un ordre naturel - et c'est ce qu'elle est. Si votre classe nécessitant un tri a un ordre naturel, définissez-le comme étant Comparable. (Une classe qui implémente l'ordre de tri de Comparable peut toujours être remplacée par un comparateur. Par contre, si la classe n'est pas comparable, il est également obligatoire de passer un comparateur pour que la commande soit possible.)
Vous avez implémenté la mauvaise interface, vous voulez Comparable
L'utilisation de @Override annotation est une pratique courante dans les éditeurs comme Eclipse, netbeans pour informer le développeur qu'il substitue/implémente une méthode classe/interface parent. C'est optionnel.
N'implémentez pas cette interface dans votre classe Item. Créez une classe new et implémentez l'interface Comparator
.
public class ItemCompare implements Comparator<Item> {
@Override
public int compare(Item a, Item b) {
if (a.getID().compareToIgnoreCase(b.getID())>0)
return 1;
else if (a.getID().compareToIgnoreCase(b.getID())<0)
return -1;
return 0;
}
}
Et ensuite, dans votre classe principale, faites ceci:
ArrayList al = new ArrayList<Item>
Collections.sort(al, new ItemCompare())