Reputation: 5811
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
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
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
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