Bonjour,
Je souhaite trier une collection d'objets de type MaClasse unis par une relation hiérarchique.
L'objectif du tri de la collection est de placer les objets pères avant les objets fils.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Class Maclasse{ public boolean estPereDe(MaClasse o2){ //retourne vrai si this est parent de o2 } }
Je met une implémentation assez proche de mon exemple pour que vous puissiez tester facilement, implémentation basée sur l'héritage java :
Je veux classer une liste de classes java en respectant leur arbre d'héritage :
J'utilise l'interface Comparator de la façon suivante :
- si class1.isAssignableFrom(class2), class1 est parent de class2 (ou égale), et class1 doit se trouver avant class 2(donc retour négatif)
- si class2.isAssignableFrom(class1), class2 est parent de class1 (ou égale), et class 2 doit se trouver avant class1 (donc retour positif)
- retour zéro si aucune relation entre class1 et class2
Ca donne :
et tout est à priori ok après tri :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 public class Test { public static void main(String[] args) { List<Class<?>> classes = new ArrayList<>(); classes.add(Integer.class); classes.add(BigDecimal.class); classes.add(Float.class); classes.add(Object.class); classes.add(String.class); classes.add(Number.class); Collections.sort(classes, new Comparator<Class<?>>() { @Override public int compare(Class<?> cls1, Class<?> cls2) { int result = 0; if (cls1.isAssignableFrom(cls2)) result = -1; else if (cls2.isAssignableFrom(cls1)) result = 1; System.out.println(cls1 + " " + cls2 + " : " + result); return result; } }); System.out.println(classes); } }
class java.math.BigDecimal class java.lang.Integer : 0
class java.lang.Float class java.math.BigDecimal : 0
class java.lang.Object class java.lang.Float : -1
class java.lang.Object class java.math.BigDecimal : -1
class java.lang.Object class java.lang.Integer : -1
class java.lang.String class java.math.BigDecimal : 0
class java.lang.String class java.lang.Float : 0
class java.lang.Number class java.math.BigDecimal : -1
class java.lang.Number class java.lang.Integer : -1
class java.lang.Number class java.lang.Object : 1
[class java.lang.Object, class java.lang.Number, class java.lang.Integer, class java.math.BigDecimal, class java.lang.Float, class java.lang.String]
Si par contre j'ajoute des classes :
Le résultat du tri devient du n'importe quoi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 classes.addAll(Arrays.asList(ArrayList.class, Test.class, Float.class, Integer.class, BigDecimal.class, Object.class, Number.class)); classes.addAll(Arrays.asList(AbstractList.class, List.class, Float.class, Object.class, String.class, Number.class));
ArrayList et AbstractList ne sont pas dans le bon ordre, et ne sont même pas comparés...[class java.lang.Object, class java.lang.Object, class java.util.ArrayList, class Test, class java.lang.Number, class java.lang.Number, class java.lang.Float, class java.lang.Float, class java.lang.Integer, class java.math.BigDecimal, interface java.util.List, class java.util.AbstractList, class java.lang.String]
J'en déduis que je fais une erreur quelque part, mais où ?
Partager