【问题标题】:Why are these duplicate cases?为什么会出现这些重复案例?
【发布时间】:2013-10-27 23:12:54
【问题描述】:

我正在尝试将用字母书写的电话号码转换为其真正的数字形式。我在 for 循环中有这个 switch 语句,它查看字符串的每个字符,但是 eclipse 说我有重复的情况('G' | 'H' | 'I', 'J' | 'K' | ' L', 'M' | 'N' | 'O') 我不明白为什么?

switch(parts[1].charAt(i)){
   case 'A' | 'B' | 'C' : number.concat("2"); break; 
   case 'D' | 'E' | 'F' : number.concat("3"); break; 
   case 'G' | 'H' | 'I' : number.concat("4"); break; 
   case 'J' | 'K' | 'L' : number.concat("5"); break; 
   case 'M' | 'N' | 'O' : number.concat("6"); break; 
   case 'P' | 'Q' | 'R' | 'S' : number.concat("7"); break; 
   case 'T' | 'U' | 'V' : number.concat("8"); break; 
   case 'W' | 'X' | 'Y' | 'Z' : number.concat("9"); break; 
}

【问题讨论】:

  • 因为这不是您处理多个案例的方式。检查您的 Java 语法:docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
  • 当有人试图猜测构造的语法时会发生这种情况......并且他们猜错了。下次,尝试检查书籍或教程中的语法。当您不熟悉一种语言时,这总是一个好主意。
  • 我了解如何使用开关,包括掉线,我想我只是不了解位操作的作用。
  • 如果你不知道|,就假装它是+。无论哪种方式,开关都不会测试单个字母,因为它会测试组合数值,丢失有关用于创建组合值的字母的信息。

标签: java string char switch-statement case


【解决方案1】:

搞笑的是,我想我知道发生了什么。

当您执行'A' | 'B' 时,您正在对A 和B 的字节值 执行按位或。您的IDE 检测到一些结果值是等效的。这绝对不是你想做的。

你想要的更像:

case 'A':
case 'B':
case 'C':
    number.concat("2");
    break;
case 'D':
    [...]

等等。

有关详细信息,请参阅http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html 上的“SwitchDemo2”。

已验证(使用 Python):

>>> ord('G') | ord('H') | ord('I')
79
>>> ord('J') | ord('K') | ord('L')
79

【讨论】:

  • 太棒了!谢谢,但请您解释一下按位运算以及为什么我的想法是错误的?
  • 没问题!按位或是一种说法,即“设置这两个二进制数共有的所有位”。因此,例如,0101 | 0010 == 0111。跟我到现在?好的。因此,对于计算机(和 Java)来说,“A”只是另一个二进制数(特别是 65 = 0b1000001)。当您将| AB 放在一起时,您将得到0b1000011。鉴于此,'G' | 'H' | 'I' == 0b1000111 | 0b1001000 | 0b1001001 == 0b1001111 == 79'J' | 'K' | 'L' == 0b1001010 | 0b1001011 | 0b1001100 == 0b1001111 == 79
  • 您的 IDE Eclipse 正在尝试通过为您执行这些操作来进行优化,并检测到它们的结果是相同的。你的想法很好;您只是使用了不正确的语法。谷歌搜索“java 多案例语法”之类的内容会有所帮助。寻求帮助并没有错,但是那里有很多参考资料。祝你好运,编码愉快!
  • (记得接受这个和未来问题的答案——如果这对你有帮助的话。)
  • @ChristianTernus 这不是 Eclipse 的事情。这不是优化或警告。这是一个真正的 Java 错误,任何 Java 编译器都需要抱怨。 JLS §14.11: "与 switch 语句关联的两个 case 常量表达式不能具有相同的值。"
【解决方案2】:

代码中的| 字符充当bitwise OR operator 使用switch 替代

switch(parts[1].charAt(i)){
    case 'A':
    case 'B':
    case 'C':
        number.concat("2");
    break;
    ...

看看这些字节值的结果

System.out.println('G' | 'H' | 'I');
System.out.println('J' | 'K' | 'L');

都打印 79

引用JLS 14.11

与 switch 语句关联的两个 case 常量表达式不能具有相同的值。

  • 这就是编译器抱怨的原因

阅读switch tutorial 了解如何使用fallthrough

【讨论】:

    【解决方案3】:

    每个字符都有一个二进制等价物。例如,“G”的二进制值是 01000111。当您应用按位或运算符“|”时,匹配 8 个二进制位中的每一个,如果其中一个为 1,则为 1,如果它们均为 0,则为 0。所以“G” ' | 'H' 相当于将 01000111 的位与 01001000 匹配(H 的二进制表示 - 它们按从 01000001 处的 'A' 开始的顺序排列)。结果是 01001111,转换为十进制后得到 79。 如果你通过手工练习,你确实会发现'G' | 'H' | 'I' 等价于 'J' | 'K' | 'L'。

    【讨论】:

    • 如其他答案所述?
    猜你喜欢
    • 2019-09-17
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-22
    • 2015-04-17
    • 2022-12-06
    相关资源
    最近更新 更多