If you hear "sorting" in Java, always think "Comparator
". If you have a Comparator
which is able to compare two elements of a given type (in your case, Class
), you can sort a list of those elements using Collections.sort(elements, comparator)
.
To write a Comparator
, you need to implement its method
public int compare(E el1, E el2);
with E
being the type of the elements, so in your case
public int compare(Class<?> c1, Class<?> c2);
because you're comparing Class
objects. You need to return -1 if c1 < c2, or 1 if c2 < c2, or 0 if they're equal (for this comparison).
Now you have two requirements that will help you implement the comparison:
- class A is subclass of class B
- class A implements the interface B
Both of these can be checked by using the method Java provides in Class
called isAssignableFrom
.
c1.isAssignableFrom(c2)
is true
if c1 "is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter" (ie c2) - so basically c1.isSuperclassOf(c2)
. For your comparison, that means, if it returns true, c1 < c2.
So let's use this to write the Comparator
.
public HierarchyComparator implements Comparator<Class<?>> {
public int compare(Class<?> c1, Class<?> c2) {
int result;
// we need to do this check because isAssignableFrom is true in this case
// and we would get an order that doesn't exist
if (c1.equals(c2)) {
return 0;
}
if (c1.isAssignableFrom(c2)) {
return -1;
} else if (c2.isAssignableFrom(c1)) {
return 1;
}
// no hierarchy
return 0;
}
}
Then, you can sort classes by
public List<Class<?>> sort(Class<?>... classes) {
List<Class<?>> result = new ArrayList<>(Arrays.asList(classes));
Collections.sort(result, new HierarchyComparator());
}