多个列表或列表和 getSublist() (Java)

Multiple lists or list and getSublist() (Java)

我有一个实现不同接口的抽象 class 'entity' 和对象(扩展 'entity')。 我还有一个包含所有这些不同对象的 ArrayList。

现在,如果我需要访问实现特定接口的所有实体(以使用其方法),我使用以下方法(returns 实现接口 'entities' 的筛选列表 'IDirectFire'):

public ArrayList<IDirectFire> getDirectFireSublist() {//direct fire sublist
    ArrayList<IDirectFire> sublist = new ArrayList();
    entities.stream().filter((it) -> (it instanceof IDirectFire)).forEach((it) -> {
        sublist.add((IDirectFire) it);
    });
    return sublist;
}

现在回答我的问题: 我应该进一步使用此方法还是应该创建一个新的 ArrayList,它存在于 'entities' 之外并且每次 'entities' 更改时我都需要手动更新?

我需要经常更新 'entities' 所以我不确定存储多个子列表并在每次 'entities' 更改时更新它们是否更有效,或者我是否应该继续使用方法来过滤 'entities' 并将方法应用于这些子列表。请记住,这些子列表也将在其他方法的循环中使用,例如:

private void resetFirestatusIDF() {//reset firestatus (IDirectFire)
    getDirectFireSublist().stream().forEach((it) -> {
        it.dfHasFired(false);
    });}

这可行吗? 提前致谢!

最好过滤一下。它将以可忽略不计的性能降低为代价创建更清晰易懂的代码,除非您过滤数百万元素,否则应该可以忽略不计。

我注意到的第二件事是您对代码片段 1 的流式使用。我会推荐您和替代方法:

> public ArrayList<IDirectFire> getDirectFireSublist() {
>      return entities.stream().filter((it) -> (it instanceof IDirectFire)).collect(Collectors.toList());
> }

Now to my question: Should I further work with this method or should I create a new ArrayList that exists besides 'entities' and that I would need to manually update every time 'entities' changes?

为什么要复制 'entites' 数据?

1) 您只能将它们放在专用列表中。在这种情况下,您不再需要 getDirectFireSublist()。

2) 您可以在两个列表之间共享它们而无需复制它们。 在这种情况下,您必须更新添加和删除的实体元素,因为只会更新修改的元素。但是实现起来还是比较直接的。

如果您只需要遍历项目的一个子集,那么创建一个新列表是一种浪费。只是 return 过滤后的流。

public Stream<IDirectFire> getDirectFire() {
    return entities.stream().filter((it) -> (it instanceof IDirectFire));
}

您也可以使用 Guava 和 return 过滤后的 Iterable

public Iterable<IDirectFire> getDirectFire() {
    return FluentIterable.from(entities).filter(IDirectFire.class);
}

然后,循环遍历其他地方的项目:

private void resetFirestatusIDF() {
    getDirectFire().forEach((it) -> it.dfHasFired(false));
}

wakjah 在评论中提到 instanceof 有点设计味道。考虑到这一点,一种替代解决方案是使用访问者模式。

public abstract class Entity {
    public abstract void acceptVisitor(EntityVisitor visitor);
    ...
}

public interface IDirectFire {
    default acceptVisitor(EntityVisitor visitor) {
        visitor.visit(this);
    }
    ...
}

public class ResetFireStatusVisitor implements EntityVisitor {
    public void visit(IDirectFire directFireEntity) {
        directFireEntity.dfHasFired(false);
    }
}

然后,循环项目:

entities.forEach(entity -> entity.acceptVisitor(new ResetFireStatusVisitor()));

ResetFireStatusVisitor 对任何实现 IDirectFire 的东西调用 dfHasFired(false)。在 EntityVisitor 中,您可以为 Entity 的其他子类型指定默认的无操作实现。

我并不是建议您对简单的案例执行此操作,但对于大型设计,这可能是解决此问题的有用答案。另一方面,它可能不会——这种模式也有它的设计味道。