Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusing code in switch statement (Java)

I would like to use a switch statement, but I am not able to construct it without either duplicating code or using an accompanying if statement. Is there a way around this?

I have 5 cases, and for all but one of them I would like to perform a certain action. So with a switch statement, I can just do:

switch(x) {
case A:
    foo();
    break;
case B:
case C:
case D:
case E:
    bar();
    break;
}

Easy. But the difficulty comes in that I also need to perform another distinct action for each one, so I can't use the fall-through feature of the cases. So I'm reduced to either

switch(x) {
case A:
    foo();
    baz(0);
    break;
case B:
    bar();
    baz(1);
    break;
case C:
    bar();
    baz(2);
    break;
case D:
    bar();
    baz(3);
    break;
case E:
    bar();
    baz(4);
    break;
}

which smells to me because of having to repeat bar() every time, or

switch(x) {
case A:
    baz(0);
    break;
case B:
    baz(1);
    break;
case C:
    baz(2);
    break;
case D:
    baz(3);
    break;
case E:
    baz(4);
    break;
}
if (x != A) { bar(); }

which doesn't duplicate any code, but it bothers me that there I need to use both switch and if.

I guess one other alternative would be to use a map, like

Map<X, Integer> m = new HashMap<X, Integer>();
m.put(A, 0);
m.put(B, 1);
m.put(C, 2);
m.put(D, 3);
m.put(E, 4);

if (m.get(x) == 0) {
    foo();
} else {
    bar();
}
baz(m.get(x));

but now I've introduced a whole data structure just to clean this up. (And when you count the initialization of the map, it's not even that much cleaner.)

Any tips?

like image 734
reo katoa Avatar asked Dec 15 '22 03:12

reo katoa


1 Answers

Is x by any chance an enum? In which case just move the method to the enum instead of switching.

enum Employee {
    SENIOR {
        @Override
        public int salary() {
            return 60;
        }
    },
    JUNIOR {
         @Override
         public int salary() {
            return 40;
         }
    };

    public abstract int salary ();
}

And calling

  employee.salary();

Is much better than switching.

Yes; you will have to duplicate method calls, but I think this is correct and clear. Or... use a constructor in your enum. Excuse contrived mix of "Employee" code with "foobar" code.

   private final boolean flag;
   Employee(int flag) {
       this.flag = flag;
   }

   public int method() {
       if(flag) {
            secondMethod();
       }
       alwaysMethod();
   }
like image 151
djechlin Avatar answered Dec 25 '22 15:12

djechlin