使用许多if-else语句(多个条件)优化函数的最佳方法是什么?

时间:2017-03-25 06:53:49

标签: java android algorithm design-patterns

优化下面代码的最佳方法或设计模式是什么?(我已经考虑过使用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;
}

3 个答案:

答案 0 :(得分:6)

您可能希望查看Guava's 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);

这有几点好处:

  • 这是一个更紧凑的语法
  • 验证范围的创建,包括最小和最大顺序,以及不重叠。

缺点是添加了番石榴,如果你还没有使用它。

答案 1 :(得分:2)

标准表驱动方法:

> Settings.timeout.seconds.ago
=> Sat, 25 Mar 2017 09:12:39 MSK +03:00

将所有条件编码为低 - 高对和相应的主要代码,并且 将所有条件放入数组中。确定主要搜索数组以找到匹配条件。

可能的增强功能(作为练习留下)包括

  1. 从文件加载表而不是硬编码
  2. 保持表格的排序,以便您可以进行二分搜索而不是线性搜索。

答案 2 :(得分:1)

我想了一会儿;重点关注:&#34;如何确保您的实施是正确的?&#34;

从这个意义上讲,我会提出一个Range类,类似于Jim提出的类。因为这样的类不仅允许您使用与范围数据紧密关联的contains()方法;但最重要的是,您可以添加以下方法:

  • boolean isOverlapping(Range other) ...你可以用它来检测你没有注意的情况,你定义了那些重叠的范围!
  • int compareTo(Range other) ...实现Comparable接口。现在你可以排序范围了。这将允许您在某个&#34;类别&#34;的范围列表时进行二进制搜索。太大了。

但是:我不会把那个&#34;专业&#34;命名到Range类;但反过来说:

public enum RangeBasedMajor {
  AC(Arrays.asList(new Range(90702, 90733), new Range(...)),
  EN(...

  private RangeBasedMajor(List<Range> ranges) ...

要点:

  • 你有一个的地方,那些&#34; majors&#34;已创建并映射到其范围
  • 您可以编写一些不错的单元测试,从该枚举中获取所有常量,然后grep其范围,确保没有范围重叠
  • 并且您仍然可以将所有信息自由地推送到Andy在他的解决方案中向您推荐的特殊类型的地图......

根据您的具体情况,此可能过度杀伤。这实际上取决于你期望事物发生变化的频率;例如:如果需要访问/处理&#34; major&#34;该计划其他部分的信息。当您的要求只是将该数字映射到字符串时(例如用于打印某些内容);然后RangeMap很好。

但是,当你有其他代码&#34; deal&#34;与&#34; Majors&#34; - 那么可能值得研究我在这里提出的一些建议。