So, we want to define the general order in the classes so that any parent class / interface is less than any derived class / interface.
Decision:
Any interface class is smaller than any object class.
to compare two interfaces, we compare the number of their super interfaces. If they are equal, we compare their names.
to compare two classes of objects, we compare the number of their superclasses. If they are equal, we compare their names.
Why is this correct. A derived class always has more ancestors than any of its superclasses. Therefore, if we compare the number of ancestors, we guarantee that superclasses go to their descendants. As for the ordering within a group of classes that have N parents, any order will be done, the alphabetical order is in order.
class ClassComparator implements Comparator<Class<?>> { @Override public int compare(Class<?> first, Class<?> second) { int areInterfaces = first.isInterface() ? 1 : 0; areInterfaces += second.isInterface() ? 2 : 0; switch (areInterfaces) { case 1 + 2: return compareNumbersThenNames(getInterfaceCount(first), getInterfaceCount(second), first, second); case 0 + 2: return -1; case 1 + 0: return 1; case 0 + 0: default: return compareNumbersThenNames(getAncestorCount(first), getAncestorCount(second), first, second); } } private int compareNumbersThenNames(int f, int s, Class<?> first, Class<?> second) { if (fs != 0) { return fs; } else { return compareByName(first, second); } } private int getAncestorCount(Class<?> objectClass) { int res=0; for (Class<?> i = objectClass; i != null ; i = i.getSuperclass()) { res++; } return res; } private int getInterfaceCount(Class<?> interfaceClass) { Set<Class<?>> superInterfaces = new HashSet<>(); addSuperinterfaces(superInterfaces, interfaceClass); return superInterfaces.size(); } private void addSuperinterfaces(Set<Class<?>>set, Class<?>interfaceClass) { for (Class<?> s : interfaceClass.getInterfaces()) { if (!set.contains(s)) { set.add(s); addSuperinterfaces(set, s); } } } private int compareByName(Class<?> a, Class<?> b) { int res = a.getSimpleName().compareTo(b.getSimpleName()); if (res != 0) { return res; } res = a.getName().compareTo(b.getName());
source share