2013-12-21 6 views
4

Я хотел бы использовать оператор switch, но я не могу его построить без дублирующего кода или с помощью прилагаемого оператора if. Есть ли способ обойти это?Повторное использование кода в операторе switch (Java)

У меня есть 5 случаев, и для всех, кроме одного из них, я хотел бы выполнить определенное действие. Так с switch заявление, я просто не могу сделать:

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

Easy. Но сложность заключается в том, что мне также необходимо выполнить другое отдельное действие для каждого из них, поэтому я не могу использовать сквозную функцию случаев. Поэтому я сводится либо

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

, который воняет мне из-за того, чтобы повторять bar() каждый раз, или

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

, не дублировать любой код, но меня беспокоит, что я необходимо использовать как switch, так и if.

Я думаю, одна другой альтернативы можно было бы использовать карту, как

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

, но теперь я представил целую структуру данных только очистить это. (И когда вы считаете инициализацию карты, это даже не так уж и больно.)

Любые советы?

+0

И вы не можете/не хотите, чтобы добавить 'если (ARG == 0) бар(), '' в baz'? –

+0

Я полагаю, что могу, но я хотел, чтобы это было более общим ... на самом деле, в коде, который у меня есть, это даже не 'bar()', это просто оператор присваивания. –

ответ

10

ли x случайно перечисление? В этом случае просто переключите метод на перечисление вместо переключения.

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

    public abstract int salary(); 
} 

И называя

employee.salary(); 

гораздо лучше, чем переключение.

Да; вам придется дублировать вызовы методов, но я думаю, что это правильно и понятно. Или ... используйте конструктор в своем перечислении. Извините за надуманное сочетание кода «Сотрудник» с кодом «foobar».

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

    public int method() { 
     if(flag) { 
      secondMethod(); 
     } 
     alwaysMethod(); 
    } 
+0

Да, 'x' является перечислением. Я думаю, что ты что-то делаешь. –

+0

Мне нравится это решение лучше всего, используя конструктор в перечислении, а не дублируя определения метода. Благодарю. –

+0

хорошая точка, я никогда не использовал абстрактные методы в перечислениях, обучения ... –

1

Я бы разделить логику байпас x в baz и создать новый переключатель есть:

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


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

Я полагаю, что ваши случаи исправлены, поэтому вы можете использовать перечисление и просто исключить один из них.

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

и условие

MyCase x; 
... 
if MyCase.A.equals(x) { 
    foo(); 
} else { 
    bar(); 
} 
baz(x); 
// or if the oridnal value is required 
baz(x.ordinal); 
Смежные вопросы