2011-11-23 21 views
0

比方说,我有这个简单的类结构:哪个是过滤List的最佳方式?

Vehicle 
|-- Bus 
`-- Car 

Bus and Car extends Vehicle 

我有List<Vehicle>。我怎样才能得到巴士或汽车?我想避免instanceof运营商。我必须使用访问者模式还是有更简单的解决方案?

+1

如果你定义一个'List ',然后有逻辑要求你只需访问'总线'在那里,那么它*可能*表示设计问题。您可能需要考虑为每个子类分别列出一个列表,尽管我可以看到有些情况下这可能不合适。 – Qwerky

+0

@Qwerky我一直在考虑两个列表,但问题是,在某些时候,我必须决定添加新车辆的列表。另外,它会使我为每种类型实现单独的方法或使用'instanceof'。我想避免所有这些在添加新型车辆的情况下。而我唯一需要确定类型的地方是获得特定车辆的列表,所以我不想在整个代码中传播特定类型。 – user219882

回答

3

东西将需要使用instanceof或等效(如Class.isInstance)。

Guava有一个方法,但确实如此:Iterables.filter。所以你可以使用:

List<Bus> buses = Lists.newArrayList(Iterables.filter(vehicles, Bus.class)); 
+0

在这种情况下,'instanceof'的用法是正确的还是坏的设计? – user219882

+2

@Tom - 我想说这取决于你为什么要过滤。如果你只想要公共汽车,因为你要为它们应用一些与票据有关的逻辑,那么在“Vehicle”接口上有一个'public boolean movesPassengers();'(或类似的)方法会更好,并过滤。如果你想要巴士特别是与Java类相关的原因(可能控制序列化的细节或某些东西?),从设计的角度来看它并没有那么糟糕。 –

+0

@Tom:*有时*这种事情是不可避免的,但它确实取决于*完全*你的场景是什么。 –

3

我看不出有什么办法避免使用你的情况instanceof运营商的,我也能看到的方式来产生比这更简单的代码(不包括番石榴帮助):

List<Bus> buses = new ArrayList<Bus>(); 
for (Vehicle v : vehicles) 
    if (v instanceof Bus) 
     buses.add(v); 
-2

如果你不想instanceOf添加字段到车辆,确定类。

相关问题