60

我需要将以下if' 更改为switch-case同时检查 a 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;
}

但我不确定我会得到什么价值。

4

13 回答 13

173

Java(版本 7 之前)在 switch/case 中不支持 String。但是您可以通过使用枚举来实现所需的结果。

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...
}
于 2012-04-20T05:09:43.760 回答
20

学会使用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;
}

switch或者开始使用 JDK 7,它包括在语句中使用字符串的能力。当然,Java无论如何都会编译switchif/ like 结构......else

于 2012-04-20T05:09:34.640 回答
20

现在每个人都在使用至少Java 7,对吧?这是原始问题的答案:

String myString = getFruitString();

switch (myString) {

    case "apple":
        method1();
        break;

    case "carrot":
        method2();
        break;

    case "mango":
        method3();
        break;

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

笔记

  • case 语句等效于 using String.equals
  • 像往常一样,字符串匹配是区分大小写的。
  • 根据文档,这通常比使用链式语句更快(如ifcHao的回答)。else
于 2017-02-09T02:13:45.200 回答
7

要降低圈复杂度,请使用地图:

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

或多态性

于 2012-04-20T07:10:01.423 回答
2

只是为了做出具体的埃默里的回答,可执行代码如下:

  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;
}
于 2013-10-03T10:15:34.947 回答
0

Java 不支持带字符串的 Switch-case。我想这个链接可以帮助你。:)

于 2012-04-20T05:57:25.057 回答
0

这是一种可能的 pre-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 不是一个好的文档。

把它当作概念证明,当作好奇心。

于 2012-04-20T09:06:16.567 回答
0

我们可以仅在数据类型兼容的 int :short、Shor、byte、Byte、int、Integer、char、Character 或 enum 类型上应用 Switch。

于 2013-06-23T11:04:50.820 回答
0

在Java SE 7String中已经实现了使用 switch 语句评估变量,因此它只在 java 7 中有效。您还可以看看这个新特性是如何在 JDK 7 中实现的。

于 2013-09-05T11:48:22.893 回答
0
    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 " );
    } 
  }}
于 2018-05-21T03:57:11.340 回答
0

Java 8 支持字符串 switchcase。

String type = "apple";

switch(type){
    case "apple":
       //statements
    break;
    default:
       //statements
    break; }
于 2018-04-13T21:45:25.667 回答
-1

不是很漂亮,但这是另一种方式:

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);
于 2017-06-01T06:26:57.040 回答
-11
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;
    }
}
于 2015-05-20T12:09:51.030 回答