【问题标题】:Checking if an instance of a specific class exists in a list检查列表中是否存在特定类的实例
【发布时间】:2016-07-26 02:49:30
【问题描述】:

好的,如果已经回答了这个问题,我们深表歉意。我试着寻找,但没有找到答案。

现在,我有一个链表实用程序类(单向链接),其中包含用于不同事物的各种通用实用程序方法。我要做的是创建一个能够将任何给定类的实例作为参数的方法,然后继续检查该类的实例是否存在于列表中,如果存在则返回 true,如果存在则返回 false没有。该列表本身包含几个不同类的实例。

该方法将与详细说明游戏板上空间内容的列表一起使用:如果该空间包含敌人,则显示敌人的图标并使该空间无法通行,如果它包含项目,则显示项目的图标等等。这里真正的问题是该方法应该能够处理任何和所有类,所以我不能使用类似的东西:

if(foo instanceof Enemy) { . . . }

这是我最初尝试做的事情: //此方法在 LinkedList 类中

public boolean exists(Object o)
{
    int i = 0;
    boolean output = false;
    //koko() returns the size of the linked list
    while(i < koko() && !output)
    {
        //alkio(i) returns an Object type reference to the entity in index i
        if(alkio(i) instanceof o.getClass())
        {
            output = true;
        }
    }
    return output;
}

但结果是这样的:https://www.dropbox.com/s/5mjr45uymxotzlq/Screenshot%202016-04-06%2001.16.59.png?dl=0

是的,这是作业(或者更确切地说,是大型作业的一部分),但老师不会在凌晨两点回答,而且我的 google-fu 太弱了。

拜托了

  • 纳尔

【问题讨论】:

  • 你为什么要输入一个对象而不是一个Class
  • 如何将类作为参数?这将是最简单的,但我并不完全意识到这是可能的......语法是什么?
  • 你认为 o.getClass 会返回什么?它返回一个Class。或者你可以写成文字MyClass.class
  • 那么你如何将它实际放入方法头中......? public boolean exists(//这里有什么?)

标签: java class linked-list variable-assignment instanceof


【解决方案1】:

instanceof的动态方法是使用Class.isInstance()方法:

确定指定的Object 是否与此Class 表示的对象分配兼容。此方法是 Java 语言 instanceof 运算符的动态等效方法。

所以,alkio(i) instanceof o.getClass() 应该写成o.getClass().isInstance(alkio(i))

【讨论】:

  • 并且只是为了确保:如果给方法的参数是 Foo 类型,并且 alkio(i) 返回的引用指向一个实例,比如...对象类,则该方法你告诉我会有返回false?
  • 反之,如果索引 i 处的实体是 Foo 类型,它会返回 true?
【解决方案2】:

这个怎么样?

public static void main(String[] args)
{
    Integer myInt = 1;
    System.out.println(exists(Arrays.asList(1, 2, 3), myInt)); //true
    System.out.println(exists(Arrays.asList("1", "2", "3"), myInt)); //false

}

/**
 * Returns whether an object exists in @list that is an instance of the class of object @o.
 */
public static boolean exists(List<?> list, Object o)
{
    return list == null || o == null ? false : list.stream().filter(o.getClass()::isInstance).findAny().isPresent();
}

【讨论】:

  • 对不起,我无法理解这个......你来这里做什么?
【解决方案3】:

如果我正确理解了您的问题,那么您需要将类传递给您的方法,而不是类的实例:

public boolean exists (Class checkClass) {
    ...
    if (item.getClass().equals(checkClass)) {
        return true;
    }
    ...
}

然后您将其称为:

if (myList.exists(Enemy.class)) {
    ...
}

但是,您应该考虑使用不同的模型,因为这显示了一些相当糟糕的面向对象设计。更好的方法是使用interface 代表地图上可以显示的所有内容。比如:

public enum MapObjectType {
    ENEMY, ALLY, WALL;
}

public interface MapObject {
    MapObjectType getType();
}

然后,可以放入代表地图的列表中的每个类都应实现此接口。例如:

public class Enemy implements MapObject {

    @Override
    public MapObjectType getType() {
        return MapObjectType.ENEMY;
    }
}

那么你的方法可能更明智:

public boolean hasObjectOfType(MapObjectType type) {
    ...
    if (item.getType().equals(type)) {
        return true;
    }
    ...
} 

【讨论】:

  • 这听起来很简洁……所以如果我理解正确的话,枚举包含了进入地图的所有东西,还有界面……界面呢?链表是否实现了该接口?接口 MapObject 是否只包含上述方法?
  • @Narmondur 枚举表示进入地图的对象类型。然后,每个对象类都应实现该接口。我将在答案中添加一个示例。
  • 我用 Class.isInstance() 方法解决了这个问题,主要是因为我怀疑老师在使用枚举时会皱眉,因为我们还没有经历过这些(我知道的唯一原因他们是我碰巧偶然发现了一门远高于我技能水平的课程,他们提到了)。最重要的是,使用我专门为不同的类制作的方法会破坏这个特定的链表实现应该具有的通用性质。无论如何,我会将此页面保存在某个地方,因为您的回复给了我宝贵的信息,我将在未来使用谢谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-03
  • 1970-01-01
  • 2015-12-27
  • 2021-08-30
相关资源
最近更新 更多