1

During recent java interview question regarding if then else was asked and question was put up in the way that if you are given with 1000 if else conditions like

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

i was asked to improvise the above code . I gave the answer that it could be improvised by using switch . But interviewer was not satisfied and asked for another approach. But i was unable to explain it. So i want to know if there is any better approach to do it.

Apologies for asking such a dumb question but i really want to know answer

user3403462
  • 121
  • 2
  • 6
  • 1
    What is meant by "*improvise*" in this context? Also, possible dup of https://stackoverflow.com/questions/1199646/long-list-of-if-statements-in-java – dhke Jun 20 '15 at 20:55
  • do you mean improve? – Fuad Jun 20 '15 at 20:55
  • Please specify exactly **what** you want to improve. Perfromance? Readability? Maintainability? For me, this looks like a typical case for a [Chain of Responsiblity](https://en.wikipedia.org/?title=Chain-of-responsibility_pattern) – Turing85 Jun 20 '15 at 20:57
  • @user3403462 What will the task be? reading values ? or it can be anything? – user3437460 Jun 20 '15 at 20:57
  • @dhke Your link is for another question. In this link the only condition is for object equality when in OP it is another condition which could be anything. Personally I'll put all conditions to the database and use some rule engine. But this is definitely not "interview" answer. – Izold Tytykalo Jun 20 '15 at 21:00
  • @IzoldTytykalo Yeah, the hashtable version needs a method to assign a unique id to condition, which is not always possible. But you can also wiggle your way around it by including the condition in the command list and looping over it taking the first one that matches. – dhke Jun 20 '15 at 21:03
  • This question is potentially very, very broad, as demonstrated by the quantity of answers. The real answer is between the interviewer's ears, because you're really asking people to guess what this interviewer was thinking. During interviews, when you get this kind of question, the person asking it already has some answer in mind. – MarsAtomic Jun 21 '15 at 02:38

7 Answers7

1

Thinking from the interviewer's perspective, the purpose of the question is to get an answer which would be segue to next question.

The below is one way to improve using Collection. For java interview Generics, Autoboxing would be a good segue and the following answer includes exactly that. You can improve it in various ways but the following would be an answer.

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

Alternatively the same can be answered with code using Apache libraries to demonstrate the use of Range utility. Here is the SO link for that and more.

Community
  • 1
  • 1
Nirmal
  • 1,229
  • 1
  • 15
  • 31
0

If condition is numeric comparison, you can create (or receive) a list of methods, and the index of method to be executed. That way, you eliminate all the if and elses and simply call methods[somePosition].Invoke()

PS:The code above isn't java, it's just an example that can be applied in any language.

Ricardo Silva
  • 1,184
  • 1
  • 11
  • 19
0

use a hash table method to key into your conditions instead of checking each condition. Hashing is order 1, so it is faster than checking all conditions via if statements.

Fuad
  • 1,419
  • 1
  • 16
  • 31
0

Multiple if statements can be improved by switch statements sometimes, switch statements can look a bit better.

However, such things are ultimately window dressing. A long list of conditionals in code often means that there has been a design flaw. The interviewer may have been looking for a appreciation of this.

You could have suggested that the conditionals could have been replaced with polymorphism.

Consider this:

 // 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);

} 

Through better design, conditionals have vanished. In general, in OO programming you want behavior to emerge from object interaction rather than long methods filled with switches and ifs.

Nathan Cooper
  • 6,262
  • 4
  • 36
  • 75
0

There are many ways to do it. We can actually make it a O(1) operation. How? Using array.

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
    }
}

There is also something known as Command Pattern which can solve this problem as well. But implementing it with array or list works nicely as well.

user3437460
  • 17,253
  • 15
  • 58
  • 106
0

The standard method to solve such problems is using a dictionary and the Command Pattern.

This however requires to you have a simple mapping condition x -> key x which may or may not be possible depending on the use case. You can still encapsulate the condition in a more extensible way:

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

where isApplicable() tests if the pre-conditions for running the ConditionCommand are met.

List<ConditionalCommand> commands;

The multiple ifs can then be condensed to looping over the command list:

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

How the command list is obtained and stored is up to you. Commands may even be pulled from a database or similar.

dhke
  • 15,008
  • 2
  • 39
  • 56
0

The best solution depends a bit on the format of the "condition", but if it just happens that, e.g. the conditions are the integers 1 to 1000 (or more generally form a dictionary of some time), then you can form a map, of e.g. Map. Then your code reduces to

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

which is cleaner, and it makes it easier to change the conditions.

phil_20686
  • 4,000
  • 21
  • 38