La comparaison est une opération qui peut être utilisée souvent dans le traitement des collections en Java. Elle sera aussi utile dans le monde des applications web écrites en PHP. Cependant, l'implémentation y sera moins formelle que celle du Java.
En Java la comparaison (et donc aussi le tri) des objets s'opère grâce à une des deux interfaces : java.lang.Comparable ou java.util.Comparator. Les deux font sont là pour exécuter la même tâche. Cependant, quelques différences subtiles les distinguent.
Différences entre Comparable et Comparator en Java
La première différence se trouve dans la méthode utilisée pour comparer les objets. Comparator possède une fonction compare() qui prend pour paramètre deux objets à comparer. Pour faire la même chose, Comparable utilise la méthode compareTo(). Elle prend comme paramètre un objet à comparer avec celui qui implémente l'interface. Les deux fonctions retourner un entier.
Résultat obtenu | Comparator.compare(Object o1, Object o2) | Comparable.compareTo(Object o2) [Object o1 = objet de la classe qui implémente l'interface Comparable) |
---|---|---|
-1 (entier négatif) | o1 < o2 | o1 < o2 |
0 (égalité) | o1 == o2 | o1 == o2 |
+1 (entier positif) | o1 > o2 | o1 > o2 |
Java implémente l'ordre naturel pour certains de ses composants. Comme suit, l'orde de ces types sera le suivant :
- Byte, Short, Integer, Long, Float, Double, BigInteger et BigDecimal: ordre numérique signé (montant, de 0 à 10000...).
- Char : ordre numérique non signé (alphabétique).
- File: ordre lexicographique sur le chemin d'accès (de a à z).
- String: ordre lexicographique (de a à z).
- Date: Ordre chronologique (du plus ancien au plus récent).
Cet ordre naturel est implémentée dans l'interface Comparable. Comme on peut déduire très facilement, afin d'utiliser un ordre plus personnalisé (par exemple selon plusieurs relations), il est conseillé de faire appel à l'interface Comparator.
L'interface Comparator permet donc de créer un objet comparateur et de l'utiliser dans eeecertaines méthodes utilitaires. Par exemple, il peut s'agir de Collection.sort() (mais aussi Arrays.list()). Cette méthode peut être appelée selon 2 manières différentes. Si elle prend comme paramètre uniquement une liste (interface List), les éléments seront comparés en ordre naturel. Par contre, si elle prend un deuxième paramètre qui est l'implémentation de l'interface Comparator, le tri s'effectuera selon la méthode compare(). Comparator peut être utilisé aussi dans SortedSet ou SortedMap.
Exemple de Comparator et Comparable en Java
Regardons maintenant deux exemples qui illustrent les nuances évoquées ci-dessus. Au tout début on verra l'implémentation de l'interface Comparator :
import java.util.Comparator; import java.util.List; import java.util.ArrayList; import java.util.Collections; public class ComparatorExemple { public static void main(String[] args) { List<Pupil> pupils = new ArrayList<Pupil>(); pupils.add(new Pupil("Marc Andre", 10)); pupils.add(new Pupil("Angeline Wolf", 16)); pupils.add(new Pupil("Marc Antoine", 16)); pupils.add(new Pupil("Julian Lome", 12)); pupils.add(new Pupil("Julian Lome", 13)); Collections.sort(pupils, new PupilComparator()); for (Pupil p : pupils) { System.out.println("Found pupil " + p.toString()); } } } class Pupil { String name; int note; public Pupil(String na, int no) { name = na; note = no; } public String getName() { return name; } public int getNote() { return note; } public String toString() { return "Pupil : " + name + " with note " + note; } } class PupilComparator implements Comparator<Pupil> { public int compare(Pupil o1, Pupil o2) { int r = ((String) o1.getName()).compareTo(o2.getName()); if (r != 0) return r; return ((Integer) o1.getNote()).compareTo(o2.getNote()); } }
Le résultat retourné par cette classe est :
Found pupil Pupil : Angeline Wolf with note 16 Found pupil Pupil : Julian Lome with note 12 Found pupil Pupil : Julian Lome with note 13 Found pupil Pupil : Marc Andre with note 10 Found pupil Pupil : Marc Antoine with note 16Concernant l'implémentation de l'interface Comparable, voici un exemple ci-dessus modifié :
import java.util.Comparator; import java.util.List; import java.util.ArrayList; import java.util.Collections; public class ComparableExemple { public static void main(String[] args) { List<Pupil> pupils = new ArrayList<Pupil>(); pupils.add(new Pupil("Marc Andre", 10)); pupils.add(new Pupil("Angeline Wolf", 16)); pupils.add(new Pupil("Marc Antoine", 16)); pupils.add(new Pupil("Julian Lome", 12)); pupils.add(new Pupil("Julian Lome", 13)); Collections.sort(pupils); for (Pupil p : pupils) { System.out.println("Found pupil " + p.toString()); } } } class Pupil implements Comparable{ String name; int note; public Pupil(String na, int no) { name = na; note = no; } public String getName() { return name; } public int getNote() { return note; } public String toString() { return "Pupil : " + name + " with note " + note; } public int compareTo(Pupil o2) { int r = name.compareTo(o2.getName()); if (r != 0) return r; return ((Integer) note).compareTo(o2.getNote()); } }
Ici le résultat de comparaison est le même que celui dans le cas d'un comparateur :
Found pupil Pupil : Angeline Wolf with note 16 Found pupil Pupil : Julian Lome with note 12 Found pupil Pupil : Julian Lome with note 13 Found pupil Pupil : Marc Andre with note 10 Found pupil Pupil : Marc Antoine with note 16