Java Switch语句 - 是否可能使用“或”/“与”?

85

我实现了一个字体系统,通过char开关语句找出应该使用哪个字母。我的字体图像中只有大写字母。我需要让' a '和'A'都具有相同的输出。而不是有两倍的情况数量,是否可以像以下这样:

char c;

switch(c){
case 'a' & 'A': /*get the 'A' image*/; break;
case 'b' & 'B': /*get the 'B' image*/; break;
...
case 'z' & 'Z': /*get the 'Z' image*/; break;
}

在Java中是否可行?


5
我想指出的是,我已经很久没有使用 switch 语句了,而且几乎每天都在编写 Java 程序。原因是我认为这种风格不好,因为它有点像 goto,并且总有更好的替代方案。在您的情况下,您可以使用Map或枚举(通常是一个不错的替代方案),并配以方法 boolean matches(char c) 和 File getImage()。 - Michael Schmeißer
5
如果这样的话,你可能也需要重新考虑使用for/while循环,因为它们也是一种goto/s形式。这就是为什么它们也包含break/continue关键字。说真的,switch并不是goto,因为它提供了自己的块作用域。它只是工具箱中的另一个工具,对于这个特定的用例来说,它也是最合适的。 - Evan Plaice
6个回答

218
你可以通过省略 break; 语句来使用 switch-case 的贯穿效果。
char c = /* whatever */;

switch(c) {
    case 'a':
    case 'A':
        //get the 'A' image;
        break;
    case 'b':
    case 'B':
        //get the 'B' image;
        break;
    // (...)
    case 'z':
    case 'Z':
        //get the 'Z' image;
        break;
}

...或者在进行switch之前将其规范化为小写大写

char c = Character.toUpperCase(/* whatever */);

switch(c) {
    case 'A':
        //get the 'A' image;
        break;
    case 'B':
        //get the 'B' image;
        break;
    // (...)
    case 'Z':
        //get the 'Z' image;
        break;
}

啊,谢谢你的例子。我之前想过将输入的字符串变成大写字母,但不确定是否可行,所以谢谢你提供第二个例子。 - GlassZee
10
实际上,如果需要保留变量 c 的大小写时,我会在 switch 语句内部使用 toUpperCase。但是感谢这种方法能够省去很多不必要的 case 语句 :-) - paxdiablo

24
上面说的是“或”而不是“与”。与的例子:110 & 011 == 010,这两种情况都不是你想要的。对于“或”,只需有两种情况,第一种情况不需要中断。例如:
case 'a':
case 'A':
  // do stuff
  break;

6
我不知道那一段对发帖者有多大帮助。 - Matt Ball
2
@MДΓΓΓБДLL:关于AND的评论是为了说明OP为什么想要OR而不是AND。 OR部分与被接受的答案相同,所以我希望它是相关的。 - Dinah

7
上述都是很好的答案。我只想补充一下,当需要检查多个字符时,使用if-else可能会更好,因为你可以像下面这样编写代码。
// switch on vowels, digits, punctuation, or consonants
char c; // assign some character to 'c'
if ("aeiouAEIOU".indexOf(c) != -1) {
  // handle vowel case
} else if ("!@#$%,.".indexOf(c) != -1) {
  // handle punctuation case
} else if ("0123456789".indexOf(c) != -1) {
  // handle digit case
} else {
  // handle consonant case, assuming other characters are not possible
}

当然,如果这变得更加复杂,我建议使用正则表达式匹配器。

3
== 0 不正确。这表示“c是否为字符串的第一个字符?”您可能想要使用 >= 0!= -1 - huon
1
@dbaupp:哎呀,你说得对。我想到的是compareTo()而不是indexOf()。已经修复了。 - scorpiodawg
1
其中一些测试可以使用 Character 中已有的方法进行替换,例如“是否为数字”的情况。 - Matt Ball

3

增强的switch/case / 带箭头的switch 语法(自Java 13起):

char c;
switch (c) {
    case 'A', 'a' -> {} // c is either 'A' or 'a'.
    case ...
}

2

关于一个有趣的Switch case陷阱的观察-->switchfall through

"break语句是必需的,因为如果没有它们,switch块中的语句会落入下一个case:" Java文档示例

连续的case片段没有break

    char c = 'A';/* switch with lower case */;
    switch(c) {
        case 'a':
            System.out.println("a");
        case 'A':
            System.out.println("A");
            break;
    }

这种情况下的输出结果是:

A

但如果你改变c的值,即char c = 'a';,那么这就变得有趣了。

这种情况下的输出结果是:

a A

尽管第二个测试用例失败了,程序仍然会继续打印A,因为缺少break导致switch将其余代码视为一个块。匹配的case标签后面的所有语句都会按顺序执行。


1
根据我对你问题的理解,在将字符传递到switch语句之前,你可以将其转换为小写。因此,你不必担心大写字母,因为它们会自动转换为小写。 为此,你需要使用以下函数:
Character.toLowerCase(c);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接