如何根据类的继承级别对类进行排序

时间:2018-06-19 06:23:25

标签: java algorithm class sorting inheritance

请创建一个算法,该算法采用类列表并以某种方式对其进行排序,无论何时

  1. A类是B类的子类

  2. A类实现接口B

  3. B的指数小于A.

    到目前为止我尝试的是,

    public void sortClasses(Class... classes) {
            List<Class> classesToSort = new ArrayList<>();
            for(Class c : classes) {
                Class superClass = c.getSuperclass();
                if(superClass != null) {
                    classesToSort.add(superClass);
                }
                Class[] interfaces = c.getInterfaces();
                if(interfaces.length > 0) {
                    classesToSort.addAll(Arrays.asList(interfaces));
                }
                classesToSort.add(c);
            }
        }
    

    我不确定这是否有效。

3 个答案:

答案 0 :(得分:0)

希望这会有所帮助。类PrintClassHierarchy需要输入要按层次结构顺序打印的类。

//sample classes for tutorial
class A{

}

class B extends A {

}


class C extends A {

}


class D extends C {

}
class E extends B {

}
    class F extends B {

    }

//print hierarchy
    public class PrintClassHierarchy {
        private static final String PADDING = "        ";
        private static final String PADDING_WITH_COLUMN = "   |    ";
        private static final String PADDING_WITH_ENTRY = "   |--- ";
        private static final String BASE_CLASS = Object.class.getName();

        private final Map<String, List<String>> subClazzEntries = new HashMap<>();

        public static void main(final String[] args) {
            new PrintClassHierarchy(
                A.class,
                B.class,
                C.class,
                D.class,
                E.class,
                F.class
            ).printHierarchy();
        }

        public PrintClassHierarchy(final Class<?>... clazzes) {
            // get all entries of tree
            traverseClasses(clazzes);
        }

        public void printHierarchy() {
            // print collected entries as ASCII tree
            printHierarchy(BASE_CLASS, new Stack<Boolean>());
        }

        private void printHierarchy(final String clazzName, final Stack<Boolean> moreClassesInHierarchy) {
            if (!moreClassesInHierarchy.empty()) {
                for (final Boolean hasColumn : moreClassesInHierarchy.subList(0, moreClassesInHierarchy.size() - 1)) {
                    System.out.print(hasColumn.booleanValue() ? PADDING_WITH_COLUMN : PADDING);
                }
            }

            if (!moreClassesInHierarchy.empty()) {
                System.out.print(PADDING_WITH_ENTRY);
            }

            System.out.println(clazzName);

            if (subClazzEntries.containsKey(clazzName)) {
                final List<String> list = subClazzEntries.get(clazzName);

                for (int i = 0; i < list.size(); i++) {
                    // if there is another class that comes beneath the next class, flag this level
                    moreClassesInHierarchy.push(new Boolean(i < list.size() - 1));

                printHierarchy(list.get(i), moreClassesInHierarchy);

                moreClassesInHierarchy.removeElementAt(moreClassesInHierarchy.size() - 1);
            }
        }
    }

    private void traverseClasses(final Class<?>... clazzes) {
        // do the traverseClasses on each provided class (possible since Java 8)
        Arrays.asList(clazzes).forEach(c -> traverseClasses(c, 0));
    }

    private void traverseClasses(final Class<?> clazz, final int level) {
        final Class<?> superClazz = clazz.getSuperclass();

        if (superClazz == null) {
            // we arrived java.lang.Object
            return;
        }

        final String name = clazz.getName();
        final String superName = superClazz.getName();

        if (subClazzEntries.containsKey(superName)) {
            final List<String> list = subClazzEntries.get(superName);

            if (!list.contains(name)) {
                list.add(name);
                Collections.sort(list); // SortedList
            }
        } else {
            subClazzEntries.put(superName, new ArrayList<String>(Arrays.asList(name)));
        }

        traverseClasses(superClazz, level + 1);
    }
}

输出:

java.lang.Object
       |--- A
               |--- B
               |       |--- E
               |       |--- F
               |--- C
                       |--- D

答案 1 :(得分:0)

如果您听到&#34;排序&#34;在Java中,始终认为&#34; Comparator&#34;。如果您有Comparator能够比较给定类型的两个元素(在您的情况下为Class),则可以使用Collections.sort(elements, comparator)对这些元素的列表进行排序。

要编写Comparator,您需要实现其方法

public int compare(E el1, E el2);

E是元素的类型,所以在你的情况下

public int compare(Class<?> c1, Class<?> c2);

因为您正在比较Class个对象。如果c1&lt;你需要返回-1。 c2,如果c2 <1,则为1。 c2,如果它们相等则为0(对于此比较)。

现在您有两个要求可以帮助您实施比较:

  1. A类是B类的子类
  2. A类实现接口B
  3. 可以使用Java Class中提供的isAssignableFrom提供的方法检查这两种方法。

    c1.isAssignableFrom(c2)
    
    如果c1&#34;与指定的Class参数所代表的类或接口相同,或者是它的超类或超接口,则

    true&#34; (即c2) - 基本上c1.isSuperclassOf(c2)。为了进行比较,这意味着,如果它返回true,则c1&lt; C2。

    因此,让我们使用它来编写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;
        }
    }
    

    然后,您可以按

    对类进行排序
    public List<Class<?>> sort(Class<?>... classes) {
        List<Class<?>> result = new ArrayList<>(Arrays.asList(classes));
        Collections.sort(result, new HierarchyComparator());
    }
    

答案 2 :(得分:-1)

您可以使用构造函数执行此操作。

List<String> listOfClasses = new ArrayList<>();
public class MyClass{
   public MyClass(){
      listOfClasses.add(this.getClass().getSimpleName());
   }
}
public class SubClass extends MyClass{
   public SubClass(){
       // here, first statement super() which calls constructor of superclass
       listOfClasses.add(this.getClass().getSimpleName());
   } 
}

因此,当您在子类中创建对象时,将调用所有类的构造函数,并以排序的方式将它们存储在listOfClasses中。