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.
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...
}
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 ...
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
String.equals
.if
-else
chaînées (comme dans réponse de cHao ).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
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;
}
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 " );
}
}}
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é.
Java 8 prend en charge le cas de commutation de chaînes.
String type = "Apple";
switch(type){
case "Apple":
//statements
break;
default:
//statements
break; }
Java ne prend pas en charge Switch-case avec String. Je suppose que this le lien peut vous aider. :)