多个列表或列表和 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
的其他子类型指定默认的无操作实现。
我并不是建议您对简单的案例执行此操作,但对于大型设计,这可能是解决此问题的有用答案。另一方面,它可能不会——这种模式也有它的设计味道。
我有一个实现不同接口的抽象 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
的其他子类型指定默认的无操作实现。
我并不是建议您对简单的案例执行此操作,但对于大型设计,这可能是解决此问题的有用答案。另一方面,它可能不会——这种模式也有它的设计味道。