为什么不能在字符串上使用 switch 语句?

此功能是否将在以后的 Java 版本中使用?

有人可以解释为什么我不能这样做吗,例如 Java 的switch语句的技术方式?

答案

Pill p = Pill.valueOf(str);
switch(p) {
  case RED:  pop();  break;
  case BLUE: push(); break;
}
ValueEnum enumval = ValueEnum.fromString(myString);
switch (enumval) {
   case MILK: lap(); break;
   case WATER: sip(); break;
   case BEER: quaff(); break;
   case OTHER: 
   default: dance(); break;
}
public class Main {

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {

      String current = args[0];
      Days currentDay = Days.valueOf(current.toUpperCase());

      switch (currentDay) {
          case MONDAY:
          case TUESDAY:
          case WEDNESDAY:
              System.out.println("boring");
              break;
          case THURSDAY:
              System.out.println("getting better");
          case FRIDAY:
          case SATURDAY:
          case SUNDAY:
              System.out.println("much better");
              break;

      }
  }

  public enum Days {

    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
  }
}

基于整数的开关可以优化为高效代码。基于其他数据类型的开关只能编译为一系列 if()语句。

因此,C&C ++ 仅允许在整数类型上进行切换,因为它与其他类型无关。

C#的设计师认为即使没有优势,样式也很重要。

Java 的设计师显然像 C 的设计师那样思考。

James Curran 简洁地说:“可以将基于整数的开关优化为非常有效的代码。基于其他数据类型的开关只能编译为一系列 if()语句。因此,C&C ++ 仅允许对整数类型进行开关,因为它与其他类型毫无意义。”

我的观点是,仅当您开始打开非基元时,您就需要开始考虑 “等于” 与 “==”。首先,比较两个字符串可能是一个相当漫长的过程,从而增加了上面提到的性能问题。其次,如果需要打开字符串,则需要忽略大小写的字符串,考虑 / 忽略语言环境的字符串,基于正则表达式的字符串。... 我赞成这样的决定,该决定可以节省大量时间语言开发人员会花费少量时间给程序员。

public static void main(String[] args) {

    switch (args[0]) {
        case "Monday":
        case "Tuesday":
        case "Wednesday":
            System.out.println("boring");
            break;
        case "Thursday":
            System.out.println("getting better");
        case "Friday":
        case "Saturday":
        case "Sunday":
            System.out.println("much better");
            break;
    }

}

除了上述良好的论据外,我还要补充指出的是,今天很多人都将switch视为 Java 程序过时的一部分(回溯至 C 时代)。

我没有完全同意这种观点,我认为switch在某些情况下可能会有其用处,至少是因为它的速度,而且else if我在某些代码中看到的else if ,它比一系列级联的数字要好。

但是确实,值得一看的是您需要一个开关的情况,看看是否不能用更多的 OO 代替它。例如 Java 1.5 + 中的枚举,也许是 HashTable 或其他一些集合(有时我很遗憾,我们没有作为一流公民的(匿名)功能,例如 Lua(没有开关)或 JavaScript)或什至是多态。

String s = "<Your String>";

switch(s.hashCode()) {
case "Hello".hashCode(): break;
case "Goodbye".hashCode(): break;
}
public final class Switch<T> {
    private final HashMap<T, Runnable> cases = new HashMap<T, Runnable>(0);

    public void addCase(T object, Runnable action) {
        this.cases.put(object, action);
    }

    public void SWITCH(T object) {
        for (T t : this.cases.keySet()) {
            if (object.equals(t)) { // This means that the class works with any object!
                this.cases.get(t).run();
                break;
            }
        }
    }
}
//#switch(target)
case "foo": code;
//#end

其他答案表明这是在 Java 7 中添加的,并提供了较早版本的解决方法。这个答案试图回答 “为什么”

Java 是对 C ++ 过于复杂的反应。它被设计为一种简单的干净语言。

String 在语言中有一些特殊情况处理,但对我来说似乎很清楚,设计师正在尝试将特殊大小写和语法糖的数量保持在最低水平。

由于字符串不是简单的原始类型,因此打开字符串非常复杂。在设计 Java 时,这不是一个常见的功能,因此与极简设计并不十分吻合。特别是因为他们决定对字符串不使用特殊情况 ==,对于 == 不适用的情况下的大小写工作会有些奇怪。

在 1.0 和 1.4 之间,语言本身几乎保持不变。 Java 的大多数增强功能都在库方面。

Java 5 改变了一切,语言得到了实质性扩展。在版本 7 和 8 中进行了进一步的扩展。我希望这种态度的变化是由 C#的崛起驱动的