【问题标题】:using method in switch case statements在 switch case 语句中使用方法
【发布时间】:2016-06-27 06:13:15
【问题描述】:

我想知道你是否可以在 switch case 的情况下使用诸如“contains()”之类的方法。我正在尝试将以下 if 语句转换为 switch 案例:

String sentence;
if(sentence.contains("abcd")){
// do command a
}
else if(sentence.contains("efgh")){
// do command b
}
else if(sentence.contains("ijkl")){
// do command c
}
else{
//do command d
}

非常感谢您的帮助。

【问题讨论】:

  • 不,你不能。 if 不能完全替换为 switch

标签: java if-statement methods switch-statement


【解决方案1】:

不,你不能。 case 语句只能比较被“切换”的事物的值。事实上,java 只是“最近”才开始支持字符串上的 switch 语句,因为它们是对象而不是原始的。通常,switch 语句仅适用于原语。据我所知,唯一的例外是字符串

【讨论】:

  • 你也可以打开枚举,它们也不是原语。
【解决方案2】:

其实你可以把这个 if 改成 switch,但是有点不可读:

    final String sentence;
    int mask = sentence.contains("abcd") ? 1 : 0;
    mask |= sentence.contains("efgh") ? 2 : 0;
    mask |= sentence.contains("ijkl") ? 4 : 0;
    switch (mask) {
    case 1:
    case 1 | 2:
    case 1 | 4:
    case 1 | 2 | 4:
        // do command a
        break;
    case 2:
    case 2 | 4:
        // do command b
        break;
    case 4:
        // do command c
        break;
    default:
        // do command d
    }
}

【讨论】:

  • 非常感谢,效果很好!但是你能解释一下这种方法是如何工作的吗?我将不胜感激。
  • @Flissie 它使用位掩码来确定找到了什么子字符串,因此如果设置了第 1 位 - 这意味着找到 abcd,但只要其他子字符串也可以出现 - 你需要几个 case 语句对于任何可能的位掩码
  • @Iłya Bursov 你知道这产生的字节码是否比 OP 的代码更高效吗?我正在开发自己的程序并且有一个类似的问题,需要两个不同的 large if...else if...else 语句增加了复杂性。这两个语句都检查完全相同的字符串(相对于我的代码,而不是 OP),只是具有不同的字符串条件(例如 sentence1.contains("astring")sentence2.contains("astring")
  • @ajent OPs 代码在这个 switch-case 中效率更高
【解决方案3】:

不,因为case 常量必须是:

  • 一个常量表达式
  • 或与switch 表达式相同类型的枚举数的名称。

方法调用都不是这些。

来自Java Language Specification, section 14.11: The switch statement

每个case 标签都有一个case 常量,它要么是常量表达式,要么是枚举常量的名称。

【讨论】:

    【解决方案4】:

    是的,假设您使用的是 JDK 7 或更高版本,您可以使用 switch 语句获得等效的代码。 JDK 7 introduced the ability to allow String objects as the expression in a switch statement。与调用 equals 方法的 if-then-else 语句链相比,这通常会产生更高效的字节码。

    String pattern;
    String sentence;
    
    if (sentence.contains(pattern))
    {
        switch (pattern)
        {
            case "abcd":
    
                // do command a
                break;
    
            case "efgh":
    
                // do command b
                break;
    
            case "ijkl":
    
                // do command c
                break;
    
            default:
    
                // do command d
                break;
        }
    }
    

    但请注意,这仅适用于 contains 方法需要一个 String 对象,并且 String 对象现在在 switch 语句中有效。您不能将其概括为与任意类型的对象一起使用。

    【讨论】:

    • 这似乎与 OP 的代码具有不同的行为,除非您先验地知道哪种模式匹配。
    • @AndyThomas OP 先验地知道哪个模式匹配;在他的示例中,他在编译时对模式进行了硬编码,并且该句子显然是在运行时从某种形式的输入中提供的。因此,我的答案的 sn-p 准确地重新创建了 OP 代码的行为。
    • OP 的代码显示了对可能匹配集的预先了解。它使用它来查找第一个匹配模式。如果事先知道匹配模式,则无需使用ifswitch 来查找它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    • 1970-01-01
    • 2014-08-05
    相关资源
    最近更新 更多