如何根据类别从列表中获取项目?

时间:2019-02-06 14:13:21

标签: java

我有一个带有列表的Entity类。我想做的是基于我作为参数放置的类来获取一个组件,例如 entity.GetComponent(TransformComponent.class);但它总是返回null。

我正在研究一个基本的基于组件的实体引擎,其中Entity是一个类,您可以将不同的组件附加到该类上,例如位置组件,纹理组件等。

这是我尝试过的:

public <T extends Component> T GetComponent(Class<T> component) {
    for(Component c : components) {
        if(component.getClass().equals(c.getClass()))
            return (T) c;
    }

    return (T) null;
}

当我尝试使用èntity.GetComponent(TransformComponent.class).getPosition()等来获取组件时,无论什么原因,它都会返回null,这使我认为仅检查它是否是类的同一实例,而不是类类型。我已经搜索了很多,但是只找到了我无法真正转换为Java的C ++工作示例。

我不知道这在Java中是否可行,但是我的下一个方法是在ComponentType中有一个Component,然后只检查List<Component>的匹配类型。 / p>

提前谢谢!

4 个答案:

答案 0 :(得分:2)

问题是您正在执行:component.getClass().equals(c.getClass())转换为:java.lang.Class.equals(c.getClass())。您没有得到T的类,而是Class的类。

您想做的是:

public <T extends Component> T GetComponent(Class<T> component) {
    for(Component c : components) {
        if(component.isInstance(c)) // check if c is an instance of component
            return (T) c;
    }

    return (T) null;
}

答案 1 :(得分:0)

public <T extends Component> T getComponent(Class<T> cls) {
    for (Component comp : components)
        if (cls.isInstance(comp))
            return (T)comp;

    return null;
}

答案 2 :(得分:0)

  1. Component.class.getClass ()返回Class.class。您需要Component.class
  2. .equals ()测试是否相等。我相信您希望任何子类型都可以匹配。

因此,具有流的解决方案将是:

public <T extends Component> T getComponent (Class<T> clazz) {
  return components.stream ()
    .filter (clazz::isInstance)
    .map (clazz::cast)
    .findFirst ()
    .orElse (null);
}

答案 3 :(得分:0)

我将使用HashMap而不是列表来确保将对象与您真正想要匹配的实际类一起存储。否则,您可能会对接口和继承感到惊讶。

HashMap<Class<? extends Component>,Component> components = new HashMap<>();
//example, how to fill your Map:
{
   components.put(Test.class, new Test());
}

//you dont realy need this delegator. You can use get() directly.
public <T extends Component> T GetComponent(Class<T> component) {
    return components.get(component):
}