Bonjour,
Je souhaite trier une collection d'objets de type MaClasse unis par une relation hiérarchique.

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
	}
}
L'objectif du tri de la collection est de placer les objets pères avant les objets fils.

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 :

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);
	}
}
et tout est à priori ok après tri :
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 :

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));
Le résultat du tri devient du n'importe quoi :

[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]
ArrayList et AbstractList ne sont pas dans le bon ordre, et ne sont même pas comparés...

J'en déduis que je fais une erreur quelque part, mais où ?