Используйте строку в случае переключения в Java

Мне нужно изменить следующее ifк switch-case во время проверки на String, чтобы улучшить цикломатическую сложность.

String value = some methodx;
if ("apple".equals(value)) {
    method1;
}

if ("carrot".equals(value)) {
    method2;
}

if ("mango".equals(value)) {
    method3;
}

if ("orange".equals(value)) {
    method4;
}

Но я не уверен, какую ценность я собираюсь получить.

13 ответов

Решение

Java (до версии 7) не поддерживает String в switch/case. Но вы можете достичь желаемого результата, используя перечисление.

private enum Fruit {
    apple, carrot, mango, orange;
}

String value; // assume input
Fruit fruit = Fruit.valueOf(value); // surround with try/catch

switch(fruit) {
    case apple:
        method1;
        break;
    case carrot:
        method2;
        break;
    // etc...
}

Все сейчас используют хотя бы Java 7, верно? Вот ответ на оригинальную задачу:

String myString = getFruitString();

switch (myString) {

    case "apple":
        method1();
        break;

    case "carrot":
        method2();
        break;

    case "mango":
        method3();
        break;

    case "orange":
        method4();
        break;
}

Заметки

  • Операторы case эквивалентны использованию String.equals,
  • Как обычно, при сопоставлении строк учитывается регистр.
  • Согласно документации, это обычно быстрее, чем при использовании цепочки if-else заявления (как в ответе Чао).

Научиться использовать else,

поскольку value никогда не будет равняться двум неравным строкам одновременно, есть только 5 возможных результатов - по одному для каждого значения, которое вам небезразлично, плюс один для "ничего из вышеперечисленного". Но поскольку ваш код не устраняет тесты, которые не могут пройти, он имеет 16 "возможных" путей (2 ^ количество тестов), из которых большинство никогда не будет выполнено.

С else, единственные пути, которые существуют - это 5, которые действительно могут произойти.

String value = some methodx;
if ("apple".equals(value )) {
    method1;
}
else if ("carrot".equals(value )) {
    method2;
}
else if ("mango".equals(value )) {
    method3;
}
else if ("orance".equals(value )) {
    method4;
}

Или начните использовать JDK 7, который включает в себя возможность использовать строки в switch заявление. Конечно, Java просто скомпилирует switch в if/else в любом случае, как построить...

Для уменьшения цикломатической сложности используйте карту:

Map<String,Callable<Object>> map = new HashMap < > ( ) ;
map . put ( "apple" , new Callable<Object> () { public Object call ( method1 ( ) ; return null ; } ) ;
...
map . get ( x ) . call ( ) ;

или полиморфизм

Просто чтобы сделать конкретный ответ Эмори, исполняемый код выглядит следующим образом:

  Map<String,Callable<USer>> map = new HashMap<String,Callable<User>>();
  map.put( "test" , new Callable<User> () { public User call (){ return fillUser("test" ); }} ) ;
  map.put( "admin" , new Callable<Utente> () { public Utente call (){  return fillUser("admin" ); }} ) ;

где пользователь является POJO, а затем

  User user = map.get(USERNAME).call();

наконец, вызываемый метод где-то:

 private User fillUser(String x){        
        User user = new User();
        // set something in User
        return user;
}

Вот возможный путь до 1.7, который я не могу рекомендовать:

public class PoorSwitch
{
    final static public int poorHash (String s) {
        long l = 0L;
        for (char c: s.toCharArray ()) {
            l = 97*l + c;
        }
        return (int) l;
    }

    public static void main (String args[])
    {
        String param = "foo";
        if (args.length == 1)
        {
            param = args[0];
        }
        // uncomment these lines, to evaluate your hash
        // test ("foo");
        // test ("bar");
        switch (poorHash (param)) {
            // this doesn't work, since you need a literal constant
            // so we have to evaluate our hash beforehand:
            // case poorHash ("foo"): {
            case 970596: {
                System.out.println ("Foo!");
                break;
            }
            // case poorHash ("bar"): {
            case 931605: {
                System.out.println ("Bar!");
                break;
            }
            default: {
                System.out.println ("unknown\t" + param);
                break;
            }
        }
    }

    public static void test (String s)
    {
        System.out.println ("Hash:\t " + s + " =\t" + poorHash (s));
    }
}

Может быть, вы могли бы работать с таким приемом в сгенерированном коде. Еще я не могу рекомендовать это. Не так много, что возможность коллизии хеша заставляет меня беспокоиться, но если что-то перепутать (вырезать и вставить), то трудно найти ошибку. 931605 не очень хорошая документация.

Воспринимайте это как доказательство концепции, как любопытство.

Java 8 поддерживает строку switchcase.

String type = "apple";

switch(type){
    case "apple":
       //statements
    break;
    default:
       //statements
    break; }

Java не поддерживает Switch-case со строкой. Я думаю, что эта ссылка может помочь вам.:)

Мы можем применить Switch только к типу данных, совместимому с типом int:short,Shor,byte,Byte,int,Integer,char,Character или enum.

Оценка String Переменные с оператором switch были реализованы в Java SE 7, и, следовательно, они работают только в Java 7. Вы также можете посмотреть, как эта новая функция реализована в JDK 7.

    String name,lname;
 name= JOptionPane.showInputDialog(null,"Enter your name");
   lname= JOptionPane.showInputDialog(null,"Enter your father name");
    if(name.equals("Ahmad")){
       JOptionPane.showMessageDialog(null,"welcome "+name);
    }
    if(lname.equals("Khan"))
   JOptionPane.showMessageDialog(null,"Name : "+name +"\nLast name :"+lname ); 

    else {
       JOptionPane.showMessageDialog(null,"try again " );
    } 
  }}

Не очень красиво, но вот другой способ:

String runFct = 
        queryType.equals("eq") ? "method1":
        queryType.equals("L_L")? "method2":
        queryType.equals("L_R")? "method3":
        queryType.equals("L_LR")? "method4":
            "method5";
Method m = this.getClass().getMethod(runFct);
m.invoke(this);
String value = someMethod();
switch(0) {
default:
    if ("apple".equals(value)) {
        method1();
        break;
    }
    if ("carrot".equals(value)) {
        method2();
        break;
    }
    if ("mango".equals(value)) {
        method3();
        break;
    }
    if ("orance".equals(value)) {
        method4();
        break;
    }
}
Другие вопросы по тегам