【问题标题】:Java : How to improvise if else statements [duplicate]Java:如何即兴发挥 if else 语句 [重复]
【发布时间】:2015-09-06 15:42:56
【问题描述】:

在最近的 Java 面试问题中,询问了 if then else 的问题,并提出问题的方式是,如果给你 1000 if else 类似的条件

if(condition 1){
      task 1
}else if (condition 2){
      task 2 
}else if (condition 3){
      task 3
}
...
else if (condition 1000){
      task 1000 
}

我被要求即兴创作上面的代码。我给出的答案是可以使用 switch 即兴创作。但面试官不满意,要求换一种方法。但我无法解释。所以我想知道是否有更好的方法来做到这一点。

抱歉问了这么愚蠢的问题,但我真的很想知道答案

【问题讨论】:

  • 在这种情况下“即兴创作”是什么意思?此外,stackoverflow.com/questions/1199646/… 的可能重复
  • 你的意思是改进吗?
  • 请具体说明什么您想要改进。性能?可读性?可维护性?对我来说,这看起来像是 Chain of Responsiblity 的典型案例
  • @user3403462 任务是什么?阅读价值观?或者它可以是任何东西?
  • @dhke 您的链接是针对另一个问题的。在这个链接中,唯一的条件是对象相等,而在 OP 中它是另一个条件,可以是任何东西。我个人会将所有条件放入数据库并使用一些规则引擎。但这绝对不是“面试”的答案。

标签: java if-statement switch-statement


【解决方案1】:

从面试官的角度思考,问题的目的是得到一个继续下一个问题的答案。

以下是使用 Collection 改进的一种方法。对于 java 面试 GenericsAutoboxing 将是一个很好的选择,下面的答案正是如此。您可以通过各种方式对其进行改进,但以下是一个答案。

 List<Integer> myRnage = new ArrayList<Integer>(1000);
 for(Integer theIndex : myRnage) {
     //do the task for theIndex at this point.
 }

也可以使用 Apache 库的代码来回答相同的问题 演示Range 实用程序的使用。这是SO link 以及更多内容。

【讨论】:

    【解决方案2】:

    如果条件是数值比较,您可以创建(或接收)方法列表,以及要执行的方法的索引。 这样,您消除了所有 if 和 else 并简单地调用 methods[somePosition].Invoke()

    PS:上面的代码不是java,只是一个例子,任何语言都可以应用。

    【讨论】:

      【解决方案3】:

      使用哈希表方法键入您的条件,而不是检查每个条件。散列是一阶的,所以它比通过 if 语句检查所有条件要快。

      【讨论】:

        【解决方案4】:

        解决此类问题的标准方法是使用字典和Command Pattern

        然而,这需要您有一个简单的映射 condition x -> key x,这可能会也可能不会,具体取决于用例。您仍然可以以更可扩展的方式封装条件:

        interface ConditionalCommand  
            extends Runnable
        {
             boolean isApplicable(conditionParams...);        
        }
        

        其中isApplicable() 测试是否满足运行ConditionCommand 的先决条件。

        List<ConditionalCommand> commands;
        

        然后可以将多个 if 压缩为循环遍历命令列表:

        for (ConditionalCommand cmd: commands) {
           if (cmd.isApplicable(params)) {
              cmd.run();
              break; // or not, which allows multiple commands to be run
           }
        }
        

        如何获取和存储命令列表取决于您。甚至可以从数据库或类似的数据库中提取命令。

        【讨论】:

          【解决方案5】:

          switch 语句有时可以改进多个 if 语句,switch 语句看起来会更好一些。

          然而,这样的事情最终只是装点门面。代码中的一长串条件通常意味着存在设计缺陷。面试官可能一直在寻求对此的欣赏。

          您可以建议条件可以是replaced with polymorphism

          考虑一下:

           // Bad implementation that replies on condtionals
          public static void Print(string animal, string quote){
          
              switch(animal){
                  case "Dog":
                      Console.WriteLine("the dog woofed " + quote);
                  return;
              case "Cat":
                      Console.WriteLine("the cat meowed " + quote);
                  return;
              }
          
          }
          
          // Better implementation that pushes the detail of how animals talk into an animal object
          public static void BetterPrint(Animal animal, string quote){
              Console.WriteLine(animal.Speak(quote));
          }
          
          
          public interface IAnimal{
          
              string Speak(string quote);
          
          } 
          

          通过更好的设计,条件已经消失。一般来说,在 OO 编程中,您希望行为来自对象交互,而不是充满开关和 if 的长方法。

          【讨论】:

            【解决方案6】:

            最佳解决方案在一定程度上取决于“条件”的格式,但如果只是发生这种情况,例如条件是 1 到 1000 的整数(或更一般地形成某个时间的字典),然后你可以形成一个地图,例如地图。然后你的代码减少到

            if(map.contains(condition)){
                map.get(condition).doTask()
            } else {
                throw new Exception("Condition has no associated task")
            }
            

            这样更干净,并且更容易更改条件。

            【讨论】:

              【解决方案7】:

              有很多方法可以做到这一点。我们实际上可以使它成为一个O(1) 操作。如何?使用数组。

              class Runner(){
                  public static void main(String[] args){
                      Task[] taskList = new Task[1000];
                      //init taskList and fill it with tasks first
              
                      Task taskToDo = taskList[condition];
                      taskToDo.execute();
                  }
              }
              
              class Task{
                  public void execute(){
                       //code for each task
                  }
              }
              

              还有一个叫做Command Pattern 的东西也可以解决这个问题。但是用arraylist 实现它也很有效。

              【讨论】:

              • 如 cmets 中所述,如果条件可以很容易地制成问题中不清楚的(数字)键,则此方法有效。
              • @dhke Bravo!你明白了……
              猜你喜欢
              • 1970-01-01
              • 2017-11-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多