Java抽象使用instanceof从List中收集类

时间:2014-06-11 20:27:30

标签: java

假设我有以下类的层次结构:

public class MainClass {

}

class A extends MainClass {

}

class B extends MainClass {

}

class C extends MainClass {

}

现在假设我有List<MainClass> classes看起来像:

 {A, MainClass, A, B, B, MainClass, C, A, C, B, A}

我希望能够通过他们的班级挑选出对象的子列表。例如,我希望能够仅提取此类A列表中的那些类(但不能提取类MainClass)。因此,使用isAssignableFrom(A.class)对我不起作用。

我目前的方法如下:

public <T extends MainClass> List<T> getClasses(List<MainClass> classes, Class classToCollect) {
    List<T> subclasses = new ArrayList<T>();

    for (MainClass clazz : classes) {
        if (clazz.getClass().isInstance(classToCollect)) {
            subclasses.add((T)clazz);
        }
    }

    return subclasses;
}

这仍然不起作用并传回一个空列表。这里给出了什么?

2 个答案:

答案 0 :(得分:6)

条件应如下所示:

for (MainClass obj : classes) {
    if (classToCollect.isInstance(obj)) {
        subclasses.add((T)obj);
    }
}

名称clazz具有误导性,因为它实际上是一个对象。

您可以在方法标题中使用Class<T>来进一步提高代码的类型安全性:

public <T extends MainClass> List<T> getClasses(List<MainClass> classes, Class<T> classToCollect) {
    ...
}

Demo on ideone.

注意:如果您将MainClass.class作为第二个参数传递(感谢,JB Nizet,以获得精彩评论),则无效。

答案 1 :(得分:0)

使用Java 8,您可以这样表达:

public <T> List<T> getClasses(List<? super T> instances, Class<T> classToCollect) {
    return instances.stream()
                    .filter(c -> c.getClass() == classToCollect)
                    .map(c -> (T) c)
                    .collect(Collectors.toList());
}