[英]What is the best way to optimize a function with many if-else statements(multiple conditions)?
什么是优化下面代码的最佳方法或设计模式是什么?(我曾考虑过使用switch语句,但是switch语句无法在单个情况下处理多个条件。)
下面是代码片段。 每个专业都由某个数值范围确定。
public String getMajor(String major) {
crnCompare = Integer.parseInt(major);
if ((crnCompare >= 90702 && crnCompare <= 90733) || (crnCompare >= 10004 && crnCompare <= 10037)) {
this.major = "AC";
} else if ((crnCompare >= 10087 && crnCompare <= 10108) || (crnCompare >= 10471 && crnCompare <= 10482) || (crnCompare >= 90024 && crnCompare <= 90071)) {
this.major = "CS";
} else if ((crnCompare >= 10109 && crnCompare <= 10158) || (crnCompare >= 90072 && crnCompare <= 90116)) {
this.major = "EC";
} else if ((crnCompare >= 90117 && crnCompare <= 90203) || (crnCompare >= 10075 && crnCompare <= 10213) || (crnCompare >= 10498 && crnCompare <= 10572)) {
this.major = "EN";
} else if ((crnCompare >= 10038 && crnCompare <= 10040) || (crnCompare >= 10214 && crnCompare <= 10255) || (crnCompare >= 10256 && crnCompare <= 10260) || (crnCompare >= 90017 && crnCompare <= 90203) || crnCompare == 11172) {
this.major = "FI";
} else if ((crnCompare >= 90670 && crnCompare <= 90790) || (crnCompare >= 11236 && crnCompare <= 11239)) {
this.major = "FS";
} else if ((crnCompare >= 90253 && crnCompare <= 90273) || (crnCompare >= 90734 && crnCompare <= 90769) || (crnCompare >= 90274 && crnCompare <= 90360) || (crnCompare >= 10261 && crnCompare <= 10393)) {
this.major = "GB";
} else if ((crnCompare >= 100394 && crnCompare <= 10429) || (crnCompare >= 90361 && crnCompare <= 90398)) {
this.major = "GLS";
} else if ((crnCompare >= 10430 && crnCompare <= 10451) || (crnCompare >= 90399 && crnCompare <= 90420)) {
this.major = "HI";
} else if ((crnCompare >= 10452 && crnCompare <= 10468) || (crnCompare >= 90422 && crnCompare <= 90436) || crnCompare == 11119) {
this.major = "IDCC";
} else if ((crnCompare >= 9437 && crnCompare <= 90438) || (crnCompare >= 10469 && crnCompare <= 10470)) {
this.major = "IPM";
} else if ((crnCompare == 90421) || (crnCompare >= 11280 && crnCompare <= 11426)) {
this.major = "ID";
} else if ((crnCompare >= 90439 && crnCompare <= 90448) || (crnCompare >= 90483 && crnCompare <= 90497)) {
this.major = "LTF";
} else if ((crnCompare >= 90504 && crnCompare <= 90535) || (crnCompare >= 10573 && crnCompare <= 10596) || crnCompare == 90785) {
this.major = "MG";
} else if ((crnCompare >= 90536 && crnCompare <= 90553) || (crnCompare >= 10598 && crnCompare <= 10616) || crnCompare == 10740) {
this.major = "MK";
} else if ((crnCompare >= 90449 && crnCompare <= 90503) || (crnCompare >= 10514 && crnCompare <= 10564) || (crnCompare == 11120) || (crnCompare == 10555) || (crnCompare == 11127)) {
this.major = "MA";
} else if ((crnCompare >= 10637 && crnCompare <= 10715) || (crnCompare == 11142) || (crnCompare == 10739) || (crnCompare >= 90575 && crnCompare <= 90622)) {
this.major = "NAS";
} else if (crnCompare >= 90554 && crnCompare <= 90574 || crnCompare == 10617 || crnCompare == 10636) {
this.major = "ML";
} else if ((crnCompare >= 90623 && crnCompare <= 10646) || (crnCompare >= 10671 && crnCompare <= 10696)) {
this.major = "PI";
} else if ((crnCompare == 90647 || crnCompare == 90649) || (crnCompare >= 10697 && crnCompare <= 10698) || crnCompare == 10756) {
this.major = "PRS";
} else if ((crnCompare >= 11341 && crnCompare <= 11420)) {
this.major = "SL";
} else if ((crnCompare >= 90650 && crnCompare <= 90668) || (crnCompare >= 10716 && crnCompare <= 10734)) {
this.major = "SO";
} else if ((crnCompare == 10735)) {
this.major = "ST";
}
return this.major;
}
您可能想研究Guava的RangeMap
类(其他类似的实现方式也可用)。
这些使您可以表达这些条件,如下所示:
RangeMap<Integer, String> rangeMap =
ImmutableRangeMap.<Integer, String>builder()
.put(Range.closed(90702, 90733), "AC")
.put(Range.closed(10004, 10037), "AC")
.put(Range.closed(10087, 10108), "EN")
.put(Range.closed(10004, 10037), "AC")
// ...
.build();
构造一次,然后查询如下:
String major = rangeMap.get(crmCompare);
有两个优点:
缺点是添加了番石榴,如果您还没有使用过的话。
标准表驱动方法:
public static class Range
{
// getters omitted for conciseness
int low;
int high;
String major;
public Range(int low, int high, String major)
{
this.low = low;
this.high = high;
this.major = major;
}
public boolean contains(int v)
{
return (v >= low && v <= high);
}
}
public static Range[] ranges = {
new Range(10004,10037,"AC"),
new Range(10087,10108,"AC"),
// etc
// Ideally this table is populated from a data file that can
// be updated at runtime without recompiling the code.
};
public String getMajor(String m)
{
int crnCompare = Integer.parseInt(m);
// Search for the matching range
for (Range r : ranges)
if (r.contains(crnCompare)) return r.major;
return null;
}
将所有条件编码为低-高对和相应的主代码,然后将所有条件放入数组中。 要确定主要搜索数组,以找到匹配条件。
可能的增强(保留为练习)包括
我想了一会儿。 关注以下方面:“如何确保实现正确?”
从这个意义上讲,我会建议一个Range类,类似于Jim提出的类。 因为这样的类使您不仅可以拥有一个与范围数据紧密相关的contains()
方法,而且还可以使您拥有一个与范围数据紧密相关的contains()
方法。 但最重要的是,您可以添加以下方法:
boolean isOverlapping(Range other)
...可以用来检测不注意的情况,并且您定义的范围可以重叠! int compareTo(Range other)
...实现Comparable接口。 现在您可以对范围进行排序 。 当某个“类别”的范围列表太大时,这将允许您执行二进制搜索。 但是:我不会将“主要”名称放到Range类中。 但是反过来:
public enum RangeBasedMajor {
AC(Arrays.asList(new Range(90702, 90733), new Range(...)),
EN(...
private RangeBasedMajor(List<Range> ranges) ...
这里的重点:
根据您的情况,这可能会过分杀伤力。 这实际上取决于您期望事物在其中发生变化的频率。 例如:如果需要访问/处理程序其他部分中的“主要”信息。 当您只需要将该数字映射到字符串时(例如用于打印内容); 那么RangeMap就可以了。
但是,当您有其他代码与“专业”打交道时,那么值得在这里提出一些建议。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.