reo katoa
reo katoa

Reputation: 5811

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?

Upvotes: 4

Views: 2301

Answers (3)

Martin Strejc
Martin Strejc

Reputation: 4347

I guess your cases are fixed so you can use enum and just exclude one of them.

public enum MyCase {
   A, B, C, D, E;
}

and the condition

MyCase x;
...
if MyCase.A.equals(x) {
    foo();
} else {
    bar();
}
baz(x);
// or if the oridnal value is required
baz(x.ordinal);

Upvotes: 0

djechlin
djechlin

Reputation: 60848

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();
   }

Upvotes: 11

Maxim Shoustin
Maxim Shoustin

Reputation: 77930

I would split logic by pass x to baz and create new switch there:

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


void baz(SomeEnum val){
 switch(val) {/* ...*/}
}

Upvotes: 1

Related Questions