将列表中的对象转换为子类

时间:2012-03-27 17:17:43

标签: java list object casting

我有一个存储一系列Actors的对象(我正在使用LibGDX),目前它正在存储GameObjects和LinkObjects,它们都扩展了Actor。我需要确保所有GameObject都链接起来,如果它们具有相同的y值(我最终会将其更改为半径,但这是测试。)要获取列表并投射它,我执行此操作:

List<Actor> actors = this.getActors();
List<GameObject> gmObjs = (List<GameObject>)(List<?>) actors;

    for(int i = 0; i<gmObjs.size(); i++) {
        for(int j=i+1; j<gmObjs.size(); j++){
            if(gmObjs.get(i).y == gmObjs.get(j).y && gmObjs.get(i).isLinked()==false){
                this.addActor(new LinkObject((gmObjs.get(i).x+gmObjs.get(j).x)/2, gmObjs.get(i).y));
            }
        }
    }

然而,它在if语句上抛出一个错误,说LinkObject无法强制转换为GameObject。我不认为我正确地投射它。有没有更好的方法从特定泛型类的对象列表中仅提取某个子类?

编辑:我意识到我真的不应该投它。我只想要一个测试来查看列表中的特定Actor是否是GameObject,如果是这样,它将它放在另一个列表中。

2 个答案:

答案 0 :(得分:2)

您可以使用instanceof运算符来检查运行时类型并根据它进行过滤。另外,根据您描述的继承层次结构来判断,GameObject和LinkObject不会相互继承;在这种情况下,你不能将一种类型转换为另一种类型;你只能在继承层次结构中向上或向下投射,而不是“横向”。

编辑: 要将GameObjects提取到单独的列表中,您必须遍历actor列表;然后,您可以使用instanceof检查每个对象是否为GameObject。然后可以将所有GameObject存储在List [GameObject]中(检查为其提供的代码ojota)。如果你不止一次调用这个提取方法,那么简单地存储GamObjects列表并让提取方法检查自上次提取GameObjects后是否已经更新了actor列表,使用布尔标志或其他内容可能是明智的。 / p>

另外,我不能肯定地从你的代码判断,但如果你添加了它可能会有用

(gmObjs.get(i) instanceof GameObject && gmObjs.get(j) instanceof GameObject)

在你的if子句的最开始;这样,只会考虑GameObjects。

另一种选择是将LinkObjects和GameObjects存储在Group对象的单独Lists中,并且只对这些列表进行操作(如果必须遍历所有Actors,则使用两者)。这几乎不会花费更多内存(只有用于存储额外List对象的内存,节点有一种或另一种方式),可以节省您提取GameObjects的成本,并避免将提取方法作为潜在来源错误。

希望有帮助,只要评论一下,如果没有回答你的问题:)

答案 1 :(得分:0)

如果您只想提取演员列表中存在的游戏对象列表,您可以执行以下操作:

List<Actor> actors =this.getActors();
List<GameObject> gameObject = new ArrayList<GameObject>();
    for (Actor actor : actors) {
        if(actor instanceof GameObject){
            gameObject.add((GameObject)actor);
        }
    }