使用参考编号的多个 if 语句



下面的代码编译并完成它的工作,但是假设我需要添加另外 100 个使用引用的 if 语句。编写多个 if 语句的最有效方法是什么?

public String getForceDetails(String ref) {
if (ref.equals("IW1")) {
setupForces();
return (ForceDetails.get(0).toString());
} else if (ref.equals("SS2")) {
setupForces();
return (ForceDetails.get(1).toString());
} else if (ref.equals("WB3")) {
setupForces();
return (ForceDetails.get(2).toString());
} else if (ref.equals("IW4")) {
setupForces();
return (ForceDetails.get(3).toString());
} else if (ref.equals("WB5")) {
setupForces();
return (ForceDetails.get(4).toString());
} else if (ref.equals("SS6")) {
setupForces();
return (ForceDetails.get(5).toString());
} else if (ref.equals("SS7")) {
setupForces();
return (ForceDetails.get(6).toString());
} else if (ref.equals("WB9")) {
setupForces();
return (ForceDetails.get(7).toString());
} else if (ref.equals("IW10")) {
setupForces();
return (ForceDetails.get(8).toString());
} else {
return "nNo such force";
}
}
private void setupForces()
{
ForceDetails.add(new starShip("IW1","Twisters",200,200,ForceState.DOCKED,10,0,0,false));
ForceDetails.add(new starShip("SS2","Enterprise",300,200,ForceState.DOCKED,0,10,20,false));
ForceDetails.add(new starShip("WB3","Droop",300,100,ForceState.DOCKED,0,0,0,false));
ForceDetails.add(new starShip("IW4","Wingers",200,400,ForceState.DOCKED,20,0,0,false));
ForceDetails.add(new starShip("WB5","Hang",400,300,ForceState.DOCKED,0,0,0,true));
ForceDetails.add(new starShip("SS6","Voyager",450,200,ForceState.DOCKED,0,15,10,false));
ForceDetails.add(new starShip("SS7","Explorer",120, 65,ForceState.DOCKED,0,4,5,false));
ForceDetails.add(new starShip("WB9","Hover",300,400,ForceState.DOCKED,0,0,0,false));
ForceDetails.add(new starShip("IW10","Flyers",200,100,ForceState.DOCKED,5,0,0,false));
}

显而易见的选择是 ref 上的 switch 语句:

switch (ref) {
case "IW1":
setupForces();
return (ForceDetails.get(0).toString());
break;
case "SS2":
setupForces();
return (ForceDetails.get(1).toString());
break;
// etc.
}

如果要执行的代码总是如下所示(调用setupForces()并获取ForceDetails的第n个元素),您还可以使用一个映射来检索n(Map<String, Integer>),您可以使用"IW1"->0和"SS2"->1等键值对填充该映射。 地图解决方案还具有一个魅力,即您不需要重复在所有情况下基本相等的代码,如果您以后必须更改它,这将非常不方便。

好吧,没有内置的解决方案。您可以做的是创建条件 -> 结果的Map并将值返回到键。

Map<String, String> mapCondToRes = new HashMap<>();
public String getForceDetails(String ref) {
setupForces();
return mapCondToRes.get(ref);
}

您可以非常轻松优雅地检查验证并放置更多条件。

在现有代码中,每次使用有效ref调用getForceDetails会导致向星际飞船ForceDetails集合添加 9 个条目。 这种行为是否有意值得怀疑,可能暗示了ForceDetails的延迟初始化。

接下来,摆脱使用映射的多个if语句肯定比转换为switch语句并将相同的多个调用复制到setupForces()更可取。 创建一个映射Map<String, starship>而不是列表并将其填充到setupForces中可能是有意义的(因此不需要在列表中使用对索引的引用的单独映射):

Map<String, starShip> forces = new HashMap<>();
private void setupForces() {
forces.put("IW1", new starShip("IW1","Twisters",200,200,ForceState.DOCKED,10,0,0,false));
forces.put("SS2", new starShip("SS2","Enterprise",300,200,ForceState.DOCKED,0,10,20,false));
// ... add other starships mapped by their ids
}
public String getForceDetails(String ref) {
if (forces.isEmpty()) {
setupForces();
}
return Optional.ofNullable(forces.get(ref))
.map(starShip::toString)
.orElse("No such force found");
}

使用 java 流,您应该阅读它们,稍后随着您在 Java 上的进展,您会发现它很有用。

对于下面的代码,我假设你在starShip类中有一个"键"值的getter("IW1""SS2""WB3"...)。

此代码还假设您无法更改当前的List方法,如果可以,Map会更好。

private static final String NO_FORCE = "nNo such force";
public String getForceDetails(String ref) {
String result = ForceDetails.stream() // <-- It's even faster if you use `parallelStream` however is known to have non-thread-safe issues
.filter(starShipItem -> Objects.equals(starShipItem.getKey(), ref))
.map(String::valueOf).findFirst()
.orElse(NO_FORCE)
;
if (NO_FORCE.equals(result)) {
return NO_FORCE;
}
setupForces();
return result;
}

另外,我建议您查看黑客等级挑战,您将在那里学到更多。

最新更新