java - switch类型 - switch如何实现
为什么我不能打开一个字符串? (10)
James Curran简洁地说道:“基于整数的开关可以优化为非常有效的代码,基于其他数据类型的开关只能编译为一系列if()语句,因此C&C ++只允许开关整数类型,因为它与其他类型毫无意义。“
我的看法是,只要你开始切换非原语,就需要开始考虑“等于”与“==”。 首先比较两个字符串可能是一个相当冗长的过程,增加了上述性能问题。 其次,如果存在切换字符串,则需要切换字符串以忽略大小写,切换字符串考虑/忽略语言环境,根据正则表达式切换字符串....我会同意为节省大量时间的决定语言开发人员需要花费少量时间为程序员服务。
为什么我不能打开一个String
?
这个功能是否会被放入更高版本的Java?
有人可以解释为什么我不能这样做,因为Java的switch
语句的技术方式有效吗?
不是很漂亮,但是对于Java 6和以下版本来说,这是另一种方式:
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);
以下是基于JeeBee的帖子的一个完整示例,使用java枚举的而不是使用自定义方法。
请注意,在Java SE 7和更高版本中,您可以改用switch语句表达式中的String对象。
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
}
}
其他答案都表示这是在Java 7中添加的,并给出了早期版本的解决方法。 这个答案试图回答“为什么”
Java是对C ++过度复杂的反应。 它被设计成一个简单的干净的语言。
字符串在语言中有一些特殊情况处理,但对我来说似乎很清楚,设计人员正在尽量减少特殊外壳和语法糖的数量。
因为字符串不是简单的基本类型,所以在字符串之间切换相当复杂。 Java在设计时并不是一个常见的功能,并且与简约设计不太吻合。 特别是因为他们已经决定不为字符串设置特殊情况==,所以在==不工作的情况下(并且)有点奇怪。
在1.0到1.4之间,语言本身几乎保持不变。 大多数Java的增强功能都在库中。
这一切都随着Java 5的改变而改变,语言大大延伸。 在版本7和8中进一步扩展。我期望这种态度的变化是由C#
在Groovy中轻而易举; 我嵌入了groovy jar,并创建了一个groovy
实用程序类来完成所有这些事情以及我在Java中发现的其他更多事情(因为我在企业中使用Java 6时遇到了问题)。
it.'p'.each{
switch ([email protected]()){
case "choclate":
myholder.myval=(it.text());
break;
}}...
基于整数的开关可以被优化为非常有效的代码。 基于其他数据类型的开关只能编译为一系列if()语句。
由于这个原因,C&C ++只允许在整数类型上进行切换,因为它对其他类型没有意义。
C#的设计者决定,即使没有优势,风格也很重要。
Java的设计者显然认为像C的设计师
如果你的代码中有一个可以打开字符串的地方,那么重构字符串可能会更好,因为它是可以打开的可能值的枚举。 当然,你可以将枚举中的字符串的潜在值限制在枚举中,这些值可能是需要的,也可能不需要。
当然你的枚举可以有'other'和fromString(String)方法的条目,那么你可以有
ValueEnum enumval = ValueEnum.fromString(myString);
switch (enumval) {
case MILK: lap(); break;
case WATER: sip(); break;
case BEER: quaff(); break;
case OTHER:
default: dance(); break;
}
如果您不使用JDK7或更高版本,则可以使用hashCode()
来模拟它。 由于String.hashCode()
通常为不同的字符串返回不同的值,并且始终为相等的字符串返回相同的值,所以它是相当可靠的(不同的字符串可以产生与注释中提到的@Lii相同的哈希码,例如"FB"
和"Ea"
)参见documentation 。
所以,代码看起来像这样:
String s = "<Your String>";
switch(s.hashCode()) {
case "Hello".hashCode(): break;
case "Goodbye".hashCode(): break;
}
这样,你在技术上开启一个int
。
或者,您可以使用以下代码:
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
是Java程序化过时的剩余部分(回到C时代)。
我并不完全赞同这种观点,我认为在某些情况下, switch
可以发挥其作用,至少是因为它的速度,反正它比某些系列的级联数字要好, else if
我在某些代码中看到的else if
......
但的确,值得关注的是你需要一个开关的情况,看看它是否不能被更多的OO所取代。 例如Java 1.5+中的枚举,可能是HashTable或其他集合(有时候我很遗憾我们没有(匿名)函数作为一等公民,就像在Lua中那样 - 它没有switch或JavaScript)甚至是多态。
public class StringSwitchCase {
public static void main(String args[]) {
visitIsland("Santorini");
visitIsland("Crete");
visitIsland("Paros");
}
public static void visitIsland(String island) {
switch(island) {
case "Corfu":
System.out.println("User wants to visit Corfu");
break;
case "Crete":
System.out.println("User wants to visit Crete");
break;
case "Santorini":
System.out.println("User wants to visit Santorini");
break;
case "Mykonos":
System.out.println("User wants to visit Mykonos");
break;
default:
System.out.println("Unknown Island");
break;
}
}
}