如何从一个通用的ArrayList中保留一个子类的所有实例

4
我有一个问题,无法找到一个干净的解决方案。
我有一个超类"Creature",它有两个子类"Human"和"Zombie"。我构建了一系列人类和僵尸,并将它们保存在ArrayList中。现在,我想获取只包含构建的人类的子列表。我以为可以使用"retainAll",但结果并不是我想要的。
你有什么建议来创建只包含子类"Zombie"对象的新ArrayList吗?
5个回答

3
您可以使用instanceof运算符。尝试以下代码:
List<Human> humans = new ArrayList<Human>();
for (Creature creature : creatures) {
    if (creature instanceof Human) {
        humans.add((Human) creature);
    }
}

3

使用Guava

List<Zombie> zombies = 
    Lists.newArrayList(Iterables.filter(creatures, Zombie.class));

1

你需要遍历元素,使用 instanceof 并构建一个新的 ArrayList。为此,我会使用 Google Guava 库。


1

看一下运算符instanceof

注意:如果您需要根据特定实例类型过滤列表,则可能存在代码异味 - 如果您提供更多有关您尝试做什么的详细信息 - 也许有更好的方法来实现它,并且重构您的代码


谢谢,实例正是我所需要的,但看起来保持分开的列表可能是更好的选择。问题在于,在程序的某个地方,我需要从所有列表中随机选择一个人,如果我保持分开的列表,它会变得有偏:/ - user1193435
@user1193435 有处理这个问题的方法。例如,维护两个列表:一个用于僵尸,一个用于人类。当您想要选择一个随机生物时,请使用概率 humans.size() / (zombies.size() + humans.size()) 选择一个人类。如果您想了解更多详细信息-这是另一回事,您可能需要提出一个新问题。 - amit
你的意思是一个二项式,其中p[人类] = [h.size / h.size + z.size] 成功=1 -> 选择一个人类 失败=0 -> 选择一个僵尸 - user1193435
@user1193435:是的,就像那样,当选择一个随机人类时,您会以概率P(h) = 1/h.size * (h.size / (h.size + z.size)) = 1/ (h.size + z.size)选择他,每个僵尸也是如此 - 因此您可以获得无偏的随机选择。不过,如果更复杂 - 应该在新问题中进行讨论。 - amit
@user:更简单易懂的方法可能是只需生成一个随机索引“index = random.nextInt(humans.size() + zombies.size())”,然后进行如下选择:“Creature randomCreature = index >= humans.size() ? zombies.get(index-humans.size()) : humans.get(index);”。换句话说,将这两个列表视为一个大列表,选择一个随机索引,然后计算出实际子列表的索引。 - Mark Peters

0
我认为没有非常干净的方法来做到这一点,只能使用其他答案中提到的instanceof和强制类型转换。
如果可能的话,我建议保持每种类型的分离列表,并仅在您需要所有生物时合并列表。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接