当前位置: 首页 > 知识库问答 >
问题:

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

吕征
2023-03-14

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

>

  • A类是B类的子类

    A类实现接口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);
            }
        }
    

    我不确定这是否有效。

  • 共有3个答案

    童化
    2023-03-14

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

    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());
       } 
    }
    

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

    王锐
    2023-03-14

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

    //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
    
    包唯
    2023-03-14

    如果您在Java中听到排序,请始终思考比较器。如果您有一个比较器,它能够比较给定类型的两个元素(在您的例子中是),您可以使用Collections.sort(元素,比较器)对这些元素的列表进行排序。

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

    public int compare(E el1, E el2);
    

    其中< code>E是元素的类型,所以在您的情况下

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

    因为您正在比较对象。如果 c1,则需要返回 -1

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

    1. 类A是类B的子类
    2. 类A实现接口B

    这两个都可以使用Java在class中提供的方法进行检查,该方法称为isAsSignablefrom

    c1.isAssignableFrom(c2)
    

    如果 c1“与指定的 Class 参数表示的类或接口相同,或者是其超类或超接口”(即 c2),则为真 - 所以基本上 c1.isSuperclassOf(c2)。为了进行比较,这意味着,如果它返回 true,则 c1

    因此,让我们用它来编写< code >比较器。

    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());
    }
    
     类似资料:
    • 问题内容: 我试图根据键中的日期对此HashMap进行排序 我的哈希图: 问题答案: 使用代替。正如已经实现的那样,它将在插入时自动排序。 或者,如果您有一个现有的并且想要基于它创建一个,则将其传递给构造函数: 也可以看看: Java教程-地图实现 Java教程-对象排序

    • 问题内容: 考虑以下是我的数组 创建了它,就像下面的代码一样: 现在,我正在尝试根据字段进行排序。 所需输出: 关于Java&Gson,谁能以最好的方式帮助解决这个问题? 非常感谢您的投入。 问题答案: 首先,解析JSON的正确方法是创建一个类来封装数据,例如: 然后: 现在您有了一个,并且想要按属性的值对其进行排序,因此可以按照此处的说明使用: 最后:

    • 问题内容: 如何使用树的值而不是键对树图进行排序? 问题答案: 您不能这样做,因为TreeMap的比较器仅针对键运行,例如,参见this 构造函数。 无论如何,您可以使用多个Collections,使用TreeMap(或HashMap)通过键查找元素,并具有SortedSet来迭代值。

    • 边走边学Java(Python背景)。简单的单词计数程序在Java7代码(不能用J8!)。 我有一个单词的哈希图:计数对。现在我需要按计数(递减顺序)排序,并打破按字母顺序使用word的联系。 我正在寻找对这个想法的反馈: 遍历HashMap中的映射项(me) 使用me.getkey=K和me.getvalue=v new map.entry reverse_me=(V,K){不确定此语法} 将r

    • 我想根据传递给类的模板参数实现一个实现开关: 如果传递的模板类型派生自特定类(此处:Serializable),则创建该类型实例的容器DataElement应派生自SerializableElement,并重载从其继承的两个纯虚拟方法(此处:unloadTo和loadFrom) 然而,如果传递的模板类型不是从Serializable派生的,那么DataElement不应该从Serializable

    • 我对give all products有wp_查询请求,需要对这两个字段进行排序:按类别 在简单查询中: 在全局$product中,存在字段“菜单\订单”,但不存在字段“产品\目录”。 我可以用wp_query吗?或者也许存在另一种方法?