web-dev-qa-db-fra.com

Utiliser une chaîne en cas de changement dans java

Je dois remplacer les if suivants par un switch-case tout en recherchant un String, afin d'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 suis pas sûr de la valeur que je vais obtenir.

57
randeepsp

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

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

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 tient à cœur, plus un pour "rien de ce qui précède". Mais comme votre code n’élimine pas les tests qui ne peuvent pas passer, il comporte 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 peuvent réellement 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 commencez à utiliser JDK 7, qui inclut la possibilité d’utiliser des chaînes dans une instruction switch. Bien sûr, Java compilera simplement la switch dans une if/else comme une construction de toute façon ...

17
cHao

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

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 équivalent à l'utilisation de String.equals.
  • Comme d'habitude, la correspondance de chaînes est sensible à la casse.
  • Selon docs , c'est généralement plus rapide que d'utiliser des instructions if-else chaînées (comme dans réponse de cHao ).
17
Suragch

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
emory

Juste pour donner une réponse concrète à 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
m.piunti
    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
latifa

Voici un moyen possible avant la 1.7, ce 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. Ce n’est pas tant que la possibilité d’une collision avec le hash m'inquiète, mais si quelque chose est mélangé (couper/coller), il est difficile de trouver l’erreur. 931605 n'est pas une bonne documentation.

Prenez cela comme une preuve de concept, comme une curiosité.

0
user unknown

L'évaluation de String avec une instruction switch a été implémentée dans Java SE 7 , et ne fonctionne donc que dans Java 7. Vous pouvez également voir comment cela fonctionne. new feature est implémenté dans JDK 7.

Java 8 prend en charge le cas de commutation de chaînes.

String type = "Apple";

switch(type){
    case "Apple":
       //statements
    break;
    default:
       //statements
    break; }
0
Yash

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

0
Sunmit Girme