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

Java 如何根据类的继承级别对类进行排序,java,algorithm,class,sorting,inheritance,Java,Algorithm,Class,Sorting,Inheritance,请创建一个算法,该算法获取一个类列表,并以某种方式对它们进行排序 A类是B类的子类 类实现接口B B的指数比A小 到目前为止我试过的是 public void sortClasses(Class... classes) { List<Class> classesToSort = new ArrayList<>(); for(Class c : classes) { Class superClass = c.getSu

请创建一个算法,该算法获取一个类列表,并以某种方式对它们进行排序

  • A类是B类的子类

  • 类实现接口B

  • 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);
            }
        }
    
    公共无效分类(类…类){
    List classesToSort=new ArrayList();
    用于(c类:类){
    Class superClass=c.getSuperclass();
    if(超类!=null){
    添加(超类);
    }
    类[]接口=c.getInterfaces();
    如果(interfaces.length>0){
    classesToSort.addAll(Arrays.asList(interfaces));
    }
    添加(c);
    }
    }
    

    我不确定这是否有效。

    您可以使用构造函数来完成

    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=newarraylist();
    公共类MyClass{
    公共MyClass(){
    添加(this.getClass().getSimpleName());
    }
    }
    公共类子类扩展了MyClass{
    公共子类(){
    //这里,第一个语句super()调用超类的构造函数
    添加(this.getClass().getSimpleName());
    } 
    }
    

    所以,当您在子类中创建对象时,所有类的构造函数都会被调用,并以排序方式存储在类列表中。

    希望这对您有所帮助。类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中的“排序”,请始终考虑“
    Comparator
    ”。如果您有一个
    比较器
    ,它能够比较给定类型的两个元素(在您的例子中是
    ),您可以使用
    集合对这些元素的列表进行排序。排序(元素,比较器)

    要编写
    比较器
    ,您需要实现它的方法

    public int compare(E el1, E el2);
    
    元素的类型为
    E
    ,因此在您的情况下

    public int compare(Class<?> c1, Class<?> c2);
    
    如果c1“与指定类参数”(即c2)表示的类或接口相同,或是其超类或超接口,则为
    true
    ——因此基本上
    c1.issupClassof(c2)
    。为了便于比较,这意味着,如果它返回true,c1 让我们用它来编写
    比较器

    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 HierarchyComparator实现comparator我们不会为您做功课。到目前为止你试过什么,到底是什么问题?有趣的问题。事实上这就是问题所在。给出一个类列表,并根据上述条件对它们进行排序。我们需要编写一个函数,它接受类列表并对其进行排序accordingly@Mureinik:我编辑了我的问题,希望这对我有所帮助,或者给我一些建议,可以做什么,或者是正确的方法。你的代码并没有对任何东西进行排序,它只是创建一个本地列表,然后返回。也许您想返回
    类排序
    ?下一个问题是该列表是否排序正确;在一些类上尝试一下,如果你遇到了一个特定的问题,就发布一个关于这个问题的问题。这是如何对类列表进行排序的?在每个构造函数中使用任何全局变量,比如list of string和call
    listOfstring.add(className)
    。然后listOfString按排序顺序包含所有类。这是错误的。这个
    比较器
    没有指定类的总顺序,因为它不是反对称的。所以,
    Collections.sort
    不起作用。@yeputons反对称性不是
    Comparator#compare
    的要求之一,请阅读其文档。它需要这里实现的“sgn(compare(x,y))=-sgn(compare(y,x))”,以及传递性。如果我遗漏了一些东西,请提供一个反例。对不起,我应该使用刚性引号,而不是一些隐含的挥手:如果
    compare(x,y)==0
    ,那么
    x
    y
    在与任意
    z
    ()进行比较时表现相同。这是不正确的:考虑<代码> B扩展了和独立<代码> C<代码>。然后
    compare(B,C)==0
    ,但是
    compare(B,A)==1
    compare(C,A)==0
    。不,这意味着您的答案违反了
    Comparator
    的约定,这可能会导致任何任意结果,例如。例如,
    B,C,A,
    是有效的排序结果:
    compare
    任意两个相邻元素的值为零。因此,
    Collection.sort
    是允许的。是使用比较器将
    Exception
    的一组直接子类与
    Exception
    本身一起排序的示例。它失败了。您是否对“真实世界使用”有任何具体限制,或者对任何可能解决问题的“适当的第二类”有任何建议?
    c1.isAssignableFrom(c2)
    
    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());
    }