62 votes

Utilisez une chaîne dans un switch case en Java

J'ai besoin de changer les if suivants en une structure switch-case tout en vérifiant une String, afin d'améliorer la complexité cyclomatique.

String value = some methodx;
switch (value) {
    case "apple":
        method1;
        break;
    case "carrot":
        method2;
        break;
    case "mango":
        method3;
        break;
    case "orange":
        method4;
        break;
}

Mais je ne suis pas sûr de la valeur que je vais obtenir.

1 votes

'si' n'est pas une boucle, c'est une instruction pour tester une certaine condition

3 votes

If loop? vraiment? Pour utiliser une déclaration switch, vous devez installer jdk7. stackoverflow.com/questions/338206/…

0 votes

docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.htm‌​l vient de lire depuis ce lien et essaie de le faire toi-même, il y a un exemple pour l'instruction switch avec des chaînes

175voto

nickdos Points 4757

Java (avant la version 7) ne prend pas en charge String dans switch/case. Mais vous pouvez obtenir le résultat souhaité en utilisant une énumération.

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

String value; // supposer une entrée
Fruit fruit = Fruit.valueOf(value); // entourer de try/catch

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

1 votes

J'ai voté pour cela, mais.. cela serait plus lent que votre "boucle".. C'est AFK la meilleure approche.

3 votes

Est-il plus lent que ? Pourquoi ?

0 votes

J'ai un problème, ma "valeur" n'est pas une constante et cette solution me pose des problèmes. Y a-t-il une solution???

20voto

cHao Points 42294

Apprenez à utiliser else.

Étant donné que valeur ne sera jamais égale à deux chaînes inégales en même temps, il n'y a que 5 résultats possibles -- un pour chaque valeur qui vous intéresse, plus un pour "aucun des cas ci-dessus". Mais parce que votre code n'élimine pas les tests qui ne peuvent pas réussir, il y a 16 chemins "possibles" (2 ^ le nombre de tests), dont la plupart ne seront jamais suivis.

Avec else, seuls les 5 chemins qui peuvent réellement se produire existent.

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

Ou commencez à utiliser JDK 7, qui inclut la capacité d'utiliser des chaînes dans une instruction switch. Bien sûr, Java va simplement compiler le switch en une structure du type if/else de toute façon...

3 votes

Cela effectue en fait un commutateur sur le code de hachage, puis effectue des ifs / else pour résoudre des collisions de hachage.

1 votes

sinon est lent :(

2 votes

@Mann: if sans else est encore plus lent, en moyenne. (Cela essayerait chaque comparaison à chaque fois. Le else est ce qui vous permet de finir tôt une fois que vous avez trouvé une correspondance.) La manière la plus propre serait en effet d'utiliser un switch, ce qui permet des optimisations comme celle mentionnée dans le commentaire avant le vôtre. Mais ce n'est pas une option dans les versions de Java avant 1.7.

7voto

emory Points 6319

Pour réduire la complexité cyclomatique, utilisez une map :

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

ou le polymorphisme

2voto

m.piunti Points 36

Juste pour concrétiser la réponse d'emory, le code exécutable est le suivant :

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

où l'utilisateur est un POJO, et ensuite

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

enfin la méthode appelée est quelque part :

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

0voto

Sunmit Girme Points 196

Java ne prend pas en charge Switch-case avec String. Je suppose que ce lien peut vous aider. :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X