【发布时间】:2011-02-28 13:49:03
【问题描述】:
在使用 Java 的 switch case 时,它除了 char 和 int,但我想提供 string case。如何让这成为可能?
【问题讨论】:
标签: java language-features switch-statement
在使用 Java 的 switch case 时,它除了 char 和 int,但我想提供 string case。如何让这成为可能?
【问题讨论】:
标签: java language-features switch-statement
您不能在 switch-case 中使用字符串(目前)。 It's on its way in Java 7.
它当前接受的类型包括char、byte、short、int、Character、Byte、Short、Integer或枚举类型。
来自 Java 语言规范:
表达式的类型必须是 char、byte、short、int、Character、Byte、Short、Integer 或枚举类型(第 8.9 节),否则会发生编译时错误。
...
以下所有条件都必须为真,否则会导致编译时错误:
- 与 switch 语句关联的每个 case 常量表达式都必须可分配(第 5.2 节)到 switch 表达式的类型。
- 没有开关标签为空。
- 与 switch 语句关联的两个 case 常量表达式不能具有相同的值。
- 最多可以有一个默认标签与同一个 switch 语句相关联。
【讨论】:
正如其他回复所述,Java(当前)不支持打开字符串值。实现相同效果的常用方法有以下三种:
将switch 替换为if ... else if ... 语句链。 (呸)。
创建并填充将字符串映射到整数代码的 HashMap,然后打开代码。
定义一个 enum 类型,其值的名称与字符串相同,使用 EType.valueOf(String) 将字符串映射到枚举值,然后打开枚举值。 (如果您需要遵守枚举值的 Java 标识符样式规则,或者如果字符串包含非标识符字符,则可能会更复杂。)
@Pete Kirkham 添加了打开字符串哈希码的“经典技巧”。但是,这样做有几个问题:
它不能正确处理提供的字符串不是所需字符串之一的情况。 (想一想:许多字符串哈希到相同的哈希码。)
哈希码很可能间隔很宽,因此 JIT 编译器必须根据哈希码值将开关编译为一系列测试/分支。这比基于String.equals() 的测试/分支要快,但它是O(N) ... 与O(1) 相比,用于编译为跳转表的开关。
【讨论】:
从 Java 6 开始,您只能开启以下类型:
JLS 14.11 The
switchstatementSwitchStatement: switch ( Expression ) SwitchBlock
Expression的类型必须是char、byte、short、int、Character、Byte、Short、Integer或 @9876543 类型,或发生编译时错误。 [...] 与 switch 语句关联的每个case常量表达式必须可分配给switch Expression的类型。
根据您的用例,您可以使用enum 代替String。与String 不同,您可以打开enum。这是一个例子:
public class EnumSwitchSample {
static enum Color {
BLACK, WHITE;
}
public static void main(String[] args) {
test(Color.valueOf("BLACK"));
// "It's black!"
test(Color.WHITE);
// "It's white!"
}
static void test(Color c) {
switch (c) {
case BLACK:
System.out.println("It's black!");
break;
case WHITE:
System.out.println("It's white!");
break;
}
}
}
然而,Java 中的enum 实际上是相当强大的,你甚至可能不需要switch 就可以了。这是一个例子:
public class EnumMemberExample {
static enum Mood {
SCREAM("I'M LOUD AND OBNOXIOUS!!!") {
@Override public String say(String statement) {
return statement.toUpperCase().replaceAll("!", "!!!");
}
},
WHISPER("Ssh... Be vewy vewy quiet...") {
@Override public String say(String statement) {
return statement.toLowerCase().replaceAll("!", "...");
}
};
final String msg;
Mood(String msg) { this.msg = msg; }
String getMessage() { return msg; }
abstract String say(String statement);
}
public static void main(String[] args) {
test(Mood.SCREAM);
// "I'M LOUD AND OBNOXIOUS!!!"
// "HELLO!!! HOW ARE YOU!!!"
test(Mood.WHISPER);
// "Ssh... Be vewy vewy quiet..."
// "hello... how are you..."
}
static void test(Mood m) {
System.out.println(m.getMessage());
System.out.println(m.say("Hello! How are you!"));
}
}
【讨论】:
switch-case 是一种语言结构,旨在仅接受整数值。你不能改变它的工作方式。
【讨论】:
我真的很绝望,你可以打开字符串的摘要。如果你喜欢这样的事情。
import java.util.zip.Adler32;
public class StringSwitch {
public static void main(String[] args) {
String arg;
if (args == null || args.length == 0) {
arg = "stackoverflow";
} else {
arg = args[0];
}
Adler32 algorithm = new Adler32();
algorithm.update(arg.getBytes());
int hash = (int) algorithm.getValue();
switch (hash) {
case 647693707:
System.out.println("Programming Q & A");
break;
case 145556093:
System.out.println("Narwhals and bacon");
break;
case 193790704:
System.out.println("How do they work?");
break;
}
}
}
【讨论】:
让我戴上教条式的帽子(你正在用 Java 编码,所以我假设你关心 OOP)
而不是问:我怎么做错了?而是问:什么是正确的做法?在这种情况下:http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html 并进行一些讨论:http://www.c2.com/cgi/wiki?ReplaceConditionalWithPolymorphism
【讨论】: