Alternative to Nested Switch Statements in Java

37,030

Solution 1

I recommend you replace each nested switch statement with a call to a procedure which then executes the nested switch code.

Write something like this instead:

    EnumOne enumOne;
    EnumTwo enumTwo = null;
    EnumTwo enumThree = null;

    switch (enumOne)
    {
       case CASE_ONE:

          nested_switch1();

       case CASE_TWO:
       case CASE_THREE:

          nested_switch2();

          break;

       default:
          break;
    }

    nested_switch1() {
          switch (enumTwo)
          {
             case A:
                enumTwo = EnumTwo.B;
                break;
             case C:
                enumTwo = EnumTwo.D;
                break;
             default:
                break;
          }

          switch (enumThree)
          {
             case AA:
                enumTwo = EnumTwo.BB;
                break;
             case CC:
                enumTwo = EnumTwo.DD;
                break;
             default:
                break;
          }

          break;
    }

nested_switch2() {
          switch(EnumTwo)
          {
             default:
                break;
          }

          switch (enumThree)
          {
             case AA:
                enumTwo = EnumTwo.XX;
                break;
             case CC:
                enumTwo = EnumTwo.YY;
                break;
             default:
                break;
          }
}

Solution 2

  1. As using a lot of switch becomes pretty hard to read.
  2. And any time a new case arises then we have to modify code and add a CASE

we can consider using polymorphism in such cases

I am going to give a simple class just to let you understand. Suppose a class earlier with switch case

class Test
{ 
    Animal a;
    public Test(Animal a)
    { 
        this.a=a;
    }

    public moveThisAnimal()
    {
        switch(this.a)
        {
            case fish:
            System.out.println("swim");
            break;

            case dog:
            System.out.println("walk");
            break;

            case bird:
            System.out.println("fly");
            break;
        }
    }
}

now we replace these switch with our polymorphism logic

Interface Animal
{
    String move();
} 

Class Dog implements Animal
{
    public String move()
    {
        return "walk";
    }
}


Class Bird implements Animal
{
    public String move()
    {
        return "fly";
    }
}


Class Fish implements Animal
{
    public String move()
    {
        return "swim";
    }
}

now we have Test class without switch case

class Test
{ 
    Animal a;
    public Test(Animal a)
    { 
        this.a=a;
    }
    public moveThisAnimal()
    {
        System.out.println(this.a.move()); // all switch case statements removed 
    }
}

and even if we have to add further cases we have to just add implementations no change here

See your complete code and see if It is possible to Do

Solution 3

If you have integers X and Y and you need to switch on both, you can combine them in some unambiguous way and switch on the combination. For example, if y < 10:

switch (x*10+y)
{
case 0: // x == y == 0
case 1: // x ==0, y == 1
///
case 10: // x == 1, y == 0
case 11: // x == y == 1
//
}
Share:
37,030

Related videos on Youtube

This 0ne Pr0grammer
Author by

This 0ne Pr0grammer

Updated on July 09, 2022

Comments

  • This 0ne Pr0grammer
    This 0ne Pr0grammer almost 2 years

    So I wrote a method today that incorporated the use of nested switch statements, and the code looked fairly clean and concise to me, but I was told that nested switch statements are not typically the best way to go as they can get confusing with the more switch statements that you add on. Here is a sample of what my code looked like:

    EnumOne enumOne;
    EnumTwo enumTwo = null;
    EnumTwo enumThree = null;
    
    switch (enumOne) {
       case CASE_ONE:
    
          switch (enumTwo){
             case A: enumTwo = EnumTwo.B; break;
             case C: enumTwo = EnumTwo.D; break;
             default: break;
          }
    
          switch (enumThree) {
             case AA: enumThree = EnumTwo.BB; break;
             case CC: enumThree = EnumTwo.DD; break;
             default: break;
          }
    
          break;
    
       case CASE_TWO:
       case CASE_THREE:
    
          switch(EnumTwo) {
             default: break;
          }
    
          switch (enumThree) {
             case AA: enumThree = EnumTwo.XX; break;
             case CC: enumThree = EnumTwo.YY; break;
             default: break;
          }
    
          break;
    
       default:
          break;
    }
    

    So my question would be, essentially, what would be a suitable alternative to these switch statements?

    • Boris the Spider
      Boris the Spider about 11 years
      So enumTwo sets it's value dependant on the value of enum's one, two and three? Why not have a method in enumTwo that returns the new value? Similar to a state pattern.
    • flup
      flup
      What are you using it for? To model a state machine?
  • XaolingBao
    XaolingBao over 8 years
    This was a very useful answer, except I found some issues with what is presented. "Class" should be lower case, as well as Overriding the move for each Animal. Also, the first example displays them as a System.out.println, but it isn't presented this way in the "correct" way. I did it this way public void moveThisAnimal() { System.out.println(this.a.move()); // all switch case statements removed } public static void main (String[] args) { Dog d = new Dog(); test t = new test(d); t.moveThisAnimal(); }
  • Lendl Leyba
    Lendl Leyba over 7 years
    A basic OOP principle.