Utiliser une chaîne dans le cas du commutateur en java


Je dois changer les if suivants en a switch-case tout en vérifiant un String, pour améliorer la complexité cyclomatique.

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

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

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

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

Mais je ne sais pas quelle valeur je vais obtenir.

Author: ManoDestra, 2012-04-20

13 answers

Java (avant la version 7) ne prend pas en charge la chaîne 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; // assume input
Fruit fruit = Fruit.valueOf(value); // surround with try/catch

switch(fruit) {
    case apple:
        method1;
        break;
    case carrot:
        method2;
        break;
    // etc...
}
 164
Author: nickdos, 2014-03-12 16:17:00

Apprenez à utiliser else.

Puisque value ne sera jamais égal à deux chaînes inégales à la fois, il n'y a que 5 résultats possibles-un pour chaque valeur qui vous intéresse, plus un pour "aucun de ce qui précède". Mais parce que votre code n'élimine pas les tests qui ne peuvent pas passer, il a 16 chemins "possibles" (2 ^ le nombre de tests), dont la plupart ne seront jamais suivis.

Avec else, les seuls chemins qui existent sont les 5 qui peut effectivement se produire.

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 commencer à utiliser JDK 7, ce qui inclut la possibilité d'utiliser des chaînes dans une instruction switch. Bien sûr, Java va simplement compiler le switch dans un if/else comme construire de toute façon...

 16
Author: cHao, 2013-09-06 18:14:49

Tout le monde utilise au moins Java 7 maintenant, non? Voici la réponse au problème d'origine:

String myString = getFruitString();

switch (myString) {

    case "apple":
        method1();
        break;

    case "carrot":
        method2();
        break;

    case "mango":
        method3();
        break;

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

Notes

  • Les instructions case sont équivalentes à l'utilisation de String.equals.
  • Comme d'habitude, la correspondance de chaîne est sensible à la casse.
  • Selon les docs , c'est généralement plus rapide que d'utiliser chained if-else déclarations (comme dans réponse de cHao ).
 14
Author: Suragch, 2017-05-23 10:31:35

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

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

Ou polymorphisme

 5
Author: emory, 2012-04-20 07:10:01

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

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

Où l'utilisateur est un POJO, puis

  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;
}
 1
Author: m.piunti, 2013-10-03 10:15:34

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

 0
Author: Sunmit Girme, 2017-05-23 11:47:05

Voici une méthode possible pré-1.7, que je ne peux pas recommander:

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

Peut-être que vous pourriez travailler avec une telle astuce dans un code généré. Sinon, je ne peux pas le recommander. Pas tellement que la possibilité d'une collision de hachage me fait du souci, mais si quelque chose est mélangé (couper-coller), il est difficile de trouver l'erreur. 931605 n'est pas une bonne documentation.

Prenez-le comme une preuve de concept, comme une curiosité.

 0
Author: user unknown, 2012-04-20 09:06:16

Nous pouvons appliquer le commutateur juste sur le type de données int compatible :court,Shor,octet,Octet,int,Entier,char,Caractère ou type enum.

 0
Author: omar, 2013-06-23 11:04:50

L'évaluation de String variables avec une instruction switch ont été implémentées dans Java SE 7 , et donc cela ne fonctionne qu'en java 7. Vous pouvez également voir comment cette nouvelle fonctionnalité est implémentée dans JDK 7.

 0
Author: Desta Haileselassie Hagos, 2013-09-05 11:48:22

Java 8 prend en charge string switchcase.

String type = "apple";

switch(type){
    case "apple":
       //statements
    break;
    default:
       //statements
    break; }
 0
Author: Yash, 2018-04-13 21:45:25
    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 " );
    } 
  }}
 0
Author: latifa, 2018-05-21 03:57:11

Pas très joli mais voici une autre façon:

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);
 -1
Author: Conete Cristian, 2017-06-01 06:26:57
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;
    }
}
 -10
Author: Triqui, 2015-05-20 12:09:51