Java 从arraylist提取子类的所有实例

Java 从arraylist提取子类的所有实例,java,generics,arraylist,Java,Generics,Arraylist,我有数组列表单位。我想编写一个函数,返回指定子类的所有对象,该子类用作参数。但是我不能让它工作。以下是我所拥有的: public static ArrayList<? extends Unit> getTheseUnits(Class<? extends Unit> specific_unit) { ArrayList<specific_unit> res = new ArrayList<>(); //'specific_unit' is

我有
数组列表单位
。我想编写一个函数,返回指定子类的所有对象,该子类用作参数。但是我不能让它工作。以下是我所拥有的:

public static ArrayList<? extends Unit> getTheseUnits(Class<? extends Unit> specific_unit) {
    ArrayList<specific_unit> res = new ArrayList<>();  //'specific_unit' is in red here. Adding '.class' or '.getClass()' after it does not resolve anything
    for (Unit u : units){
        if (u instanceof specific_unit){
            res.add(u);
        }
    }
    return res;
}

publicstaticarraylist不能对变量使用
instanceof
。相反,您应该使用
isInstance

只需替换此行:

if (u instanceof specific_unit) {

按类别筛选它们:

public static List<Unit> getUnitsByClass(Class<? extends Unit> specificClass, List<? extends Unit> units) {
     return units.stream()
                 .filter(e -> e.getClass().equals(specificClass))
                 .collect(Collectors.toList());
}

publicstaticlist getUnitsByClass(Class如果更改方法签名,它可以工作:

public static <T extends Unit> ArrayList<T> getTheseUnits(Class<T> specific_unit) {
    ArrayList<T> res = new ArrayList<>();
    for (Unit u : units){
        if (specific_unit.isAssignableFrom(u.getClass()) {
            res.add(u);
        }
    }
    return res;
}
publicstaticarraylistgettheseunits(特定于类的单元){
ArrayList res=新的ArrayList();
用于(单位u:单位){
if(特定的_单位.isAssignableFrom(u.getClass()){
决议增补(u);
}
}
返回res;
}
只需为泛型(
)使用特定类型,而不是通配符(
)。这是创建返回类型(
ArrayList
)所必需的

您还应该使用
isAssignableFrom()
而不是
instanceof
。请注意
isAssignableFrom()
还检查子类型

请再次检查此代码,因为我尚未对其进行测试。

请尝试以下操作:

public static <T extends Unit> ArrayList<T> getTheseUnits(Class<T> specific_unit) {
    ArrayList<T> res = new ArrayList<T>();
    for (Unit u : units){
        if (specific_unit.isInstance(u)){
            res.add((T) u);
        }
    }
    return res;
}
publicstaticarraylistgettheseunits(特定于类的单元){
ArrayList res=新的ArrayList();
用于(单位u:单位){
if(单位为单位单位(u)){
决议添加((T)u);
}
}
返回res;
}

也许您可以尝试在声明和返回中不使用类,而是使用接口(因此使用List而不是ArrayList,使用Unit而不是SpecificUnit)。我已将类和实例重命名为java样式…例如:

public static List<? extends Unit> getTheseUnits(Class<? extends Unit> specificUnit, List<Unit> units) {
    List<Unit> res = new ArrayList<Unit>();
    for (Unit u : units){
        if (specificUnit.isInstance(u)){
            res.add(u);
        }
    }
    return res;
}

public static List“It is red in here”(此处为红色)转换为编译器错误。在尝试处理此类代码之前,也许您真的应该学习一些java基础知识。意思是:在转向复杂的泛型类型用法之前,先了解编译器错误等基本概念(以及如何读取它们)归结起来就是:您不能使用变量名作为泛型类型,因此
ArrayList
不是正确的Java声明。@Jägermeister我知道这是编译器错误,但是eclipse仅仅声明
特定的单元不能被解析
只是为了完整性:他的方法仍然不会像他那样编译在创建“返回值”arraylist时,还使用specific_unit作为类型参数。您可能还需要更新关于该方面的答案。我认为您的答案有点短。他似乎对所有泛型类型都不了解;因此他可能无法理解您的“specific unit.class”不是他的“特定单位"变量。@Jägermeister OP的
specific_unit
变量属于class类型,我将其重命名为
specific class
,以使其更清楚。@Jägermeister也许我不知道如何始终正确地获得泛型,但我不是傻瓜。谢谢你的回答@SashaSalauyou@CoderinoJavarino我不是有意侮辱你,但你是对的,我可以我们建议“总体上”改进答案(并不意味着你可能有问题),为什么在类型不相关时使用“T”;因此“?”就可以了?@Jägermeister类型
T
需要定义一个新的
ArrayList
(问题中的编译器错误)。
public static <T extends Unit> ArrayList<T> getTheseUnits(Class<T> specific_unit) {
    ArrayList<T> res = new ArrayList<T>();
    for (Unit u : units){
        if (specific_unit.isInstance(u)){
            res.add((T) u);
        }
    }
    return res;
}
public static List<? extends Unit> getTheseUnits(Class<? extends Unit> specificUnit, List<Unit> units) {
    List<Unit> res = new ArrayList<Unit>();
    for (Unit u : units){
        if (specificUnit.isInstance(u)){
            res.add(u);
        }
    }
    return res;
}