Java 如何避免搜索例程中的instanceof?
目前,我正在对项目列表执行线性搜索,如下所示:Java 如何避免搜索例程中的instanceof?,java,oop,polymorphism,Java,Oop,Polymorphism,目前,我正在对项目列表执行线性搜索,如下所示: private Item getKey(ArrayList<Item> inventory) { for(Item item : inventory) { if(item instanceof Key) { return item; } } return null; } private Item getKey(ArrayList库存){ 用于(项目:库存)
private Item getKey(ArrayList<Item> inventory) {
for(Item item : inventory) {
if(item instanceof Key) {
return item;
}
}
return null;
}
private Item getKey(ArrayList库存){
用于(项目:库存){
if(项目实例键){
退货项目;
}
}
返回null;
}
我听说使用instanceof
被认为是一种“代码气味”。通常,为了避免使用instanceof
我会使用多态性(如中所述),然而,在这种情况下,我很难看到如何使用多态性
因此,我想知道是否有一种方法可以消除
instanceof
的需要,或许可以使用另一种技术,例如更加关注OOD的多态性?您的案例与您的链接不同。我不认为您在本例中的代码是“代码气味”。正如@shmosel提到的那样 此方法中没有缺陷 但您可以使代码更易于重用,因为:
private Item getKey(ArrayList<Item> inventory) {
return getAnItemByType(inventory, Key.class);
}
private Item getAnItemByType(ArrayList<Item> inventory, Class<? extends Item> type) {
for(Item item : inventory) {
if(type.isInstance(item)) {
return item;
}
}
return null;
}
private Item getKey(ArrayList库存){
返回getAnItemByType(库存,Key.class);
}
private Item getAnItemByType(ArrayList inventory,Class如果您想要一个使用多态性而不是instanceof
的解决方案,您需要在超类型中定义一个isKey()
方法,并为符合键条件的子类型重写它:
public class Item {
public boolean isKey() {
return false;
}
}
class Key extends Item {
@Override
public boolean isKey() {
return true;
}
}
然后,您的解决方案变成:
private Item getKey(ArrayList<Item> inventory) {
for(Item item : inventory) {
if(item.isKey()) {
return item;
}
}
return null;
}
你需要缩小。缺陷不在这个方法中。而是因为你正试图从项
@shmosel的列表中提取一个键
。啊,我明白你的意思。有没有更好的方法来表示库存的想法?你认为额外的库存
类会有帮助吗?很难说没有更多上下文。@shmosel好的,我理解。谢谢你的提示:)这在同一级别上仍然有缺陷。类似地,您可以创建一个int-type
字段(或者一个enum-type
字段)。但是如果你有一个项
对象的列表,然后想从中分离出键
、Foo
、条
和蓝精灵
对象,那么一切都会崩溃。问题是:为什么对象存储在同一个列表中,而它们在概念上如此不同,以至于之后需要按其类型对它们进行拆分?也许,它们首先应该存储在不同的列表中……是的,我同意这并不理想。但是,如果没有更广泛的设计背景,很难知道其他哪些约束可能会在这个决策中发挥作用。我试图尽可能具体地回答OP的问题。
private Optional<Item> getKey(ArrayList<Item> inventory) {
return inventory.stream().filter( item -> item.isKey() ).findFirst();
}