有什么方法可以在 Java 8 中将 Switch 语句的 Case 标签检索为集合?
Is there any way to retrieve the Case Labels of a Switch Statement as a Collection in Java 8?
我已经为文本文件中的典型文本格式(专有)编写了一个解析器。解析器的主要任务之一是转换调用中的函数名称,其次是改变参数 and/or 它们在调用中的位置。
示例:
Func1(bla1,bla2,bla3)
变成
Func2(bla1) // again, licensing issues, so cannot show the actual file
至少有 50 个独立的此类函数。该程序运行良好。唯一的问题是,如果将来添加一些新函数,我将不得不改变两件事,一个 ArrayList ,它包含所有需要修改其调用的函数的名称,以及一个实际修改调用的 switch 语句。可能会发生这样的情况,一个特定的函数名称作为一个案例出现在 switch 语句中,但我是一个健忘的怪胎,函数名称不存在于 ArrayList 中。
我在想的是,如果我可以让 Java 为我生成那个 ArrayList(它只是一个字符串列表,每个条目都是一个 case 标签),它可能会有所帮助。
Java 8 中有什么方法可以做到这一点吗?
示例:
String functionName = "";
switch(functionName) {
case "Func1":
break;
case "Func2":
break;
//bla bla bla
default:
//whatever
}
List<String> functionNames = <some code which returns a Collection of all case names>;
来自 Java 语言规范 : 14.11. The switch Statement
click the link , you can see that cases of the Switch can be a ConstantExpression or an EnumConstantName and following the definition of the ConstantExpression here click the link .
所以每个case语句中的值必须是compile-time个与switch值相同数据类型的常量值(文字,枚举常量,或final常量变量:用final修饰符标记并初始化)。
您正在寻找问题的答案:是否可以在运行时知道案例数量? 不可以,因为 cases 必须是编译时常量。
public class Swith {
public static void main(String[] args) {
List<String> lst = new ArrayList<>();
switch (lst.get(0)) {
case lst.get(0): //Compilation error : case expressions must be constant expressions
break;
default:
break;
}
}
}
无法列出来自 switch
的 case
标签。
但是,您可以维护一个 Map
,它将函数名称映射到它们对应的 actions-to-be-performed:
Map<String, Runnable> functions = Map.of(
"func1", () -> doSomething(),
"func2", () -> doSomethingElse(),
...
);
要获取函数名,您可以使用keySet()
获取所有函数名(或使用containsKey
检查函数名是否存在)。而不是 switch 语句,你可以只使用
functions.get(functionName).run();
请注意,我使用了 Runnable
作为映射值,它允许执行一些代码,无需输入。那是因为您没有显示您的 switch case 实际执行的操作,或者 " 改变参数 and/or 它们在调用中的位置" 实际看起来像什么。您可能想用更合适的内容替换 Runnable
。
您不能从开关中动态派生 case 语句的集合。但是,您可以创建一个函数枚举并在开关中使用它,然后 assemble 您的列表。例如...
public enum Function {
FUNC1("func1"), FUNC2("func2"), ... ;
private String functionName;
private Function(String functionName) { ... }
public String functionName() { ... }
public static Function byFunctionName(String functionName) { ... }
}
找到与您当前打开的字符串相匹配的函数实例并打开该函数。
Function function = Function.byFunctionName(functionName);
switch (function) {
case FUNCT1: ...
case FUNCT2: ...
... etc ...
}
并且可以从同一个枚举创建函数名称列表。
List<String> functionNames = Arrays.stream(Function.values())
.map(e -> e.functionName())
.collect(Collectors.toList());
我已经为文本文件中的典型文本格式(专有)编写了一个解析器。解析器的主要任务之一是转换调用中的函数名称,其次是改变参数 and/or 它们在调用中的位置。
示例:
Func1(bla1,bla2,bla3)
变成
Func2(bla1) // again, licensing issues, so cannot show the actual file
至少有 50 个独立的此类函数。该程序运行良好。唯一的问题是,如果将来添加一些新函数,我将不得不改变两件事,一个 ArrayList ,它包含所有需要修改其调用的函数的名称,以及一个实际修改调用的 switch 语句。可能会发生这样的情况,一个特定的函数名称作为一个案例出现在 switch 语句中,但我是一个健忘的怪胎,函数名称不存在于 ArrayList 中。
我在想的是,如果我可以让 Java 为我生成那个 ArrayList(它只是一个字符串列表,每个条目都是一个 case 标签),它可能会有所帮助。
Java 8 中有什么方法可以做到这一点吗?
示例:
String functionName = "";
switch(functionName) {
case "Func1":
break;
case "Func2":
break;
//bla bla bla
default:
//whatever
}
List<String> functionNames = <some code which returns a Collection of all case names>;
来自 Java 语言规范 : 14.11. The switch Statement
click the link , you can see that cases of the Switch can be a ConstantExpression or an EnumConstantName and following the definition of the ConstantExpression here click the link .
所以每个case语句中的值必须是compile-time个与switch值相同数据类型的常量值(文字,枚举常量,或final常量变量:用final修饰符标记并初始化)。
您正在寻找问题的答案:是否可以在运行时知道案例数量? 不可以,因为 cases 必须是编译时常量。
public class Swith {
public static void main(String[] args) {
List<String> lst = new ArrayList<>();
switch (lst.get(0)) {
case lst.get(0): //Compilation error : case expressions must be constant expressions
break;
default:
break;
}
}
}
无法列出来自 switch
的 case
标签。
但是,您可以维护一个 Map
,它将函数名称映射到它们对应的 actions-to-be-performed:
Map<String, Runnable> functions = Map.of(
"func1", () -> doSomething(),
"func2", () -> doSomethingElse(),
...
);
要获取函数名,您可以使用keySet()
获取所有函数名(或使用containsKey
检查函数名是否存在)。而不是 switch 语句,你可以只使用
functions.get(functionName).run();
请注意,我使用了 Runnable
作为映射值,它允许执行一些代码,无需输入。那是因为您没有显示您的 switch case 实际执行的操作,或者 " 改变参数 and/or 它们在调用中的位置" 实际看起来像什么。您可能想用更合适的内容替换 Runnable
。
您不能从开关中动态派生 case 语句的集合。但是,您可以创建一个函数枚举并在开关中使用它,然后 assemble 您的列表。例如...
public enum Function {
FUNC1("func1"), FUNC2("func2"), ... ;
private String functionName;
private Function(String functionName) { ... }
public String functionName() { ... }
public static Function byFunctionName(String functionName) { ... }
}
找到与您当前打开的字符串相匹配的函数实例并打开该函数。
Function function = Function.byFunctionName(functionName);
switch (function) {
case FUNCT1: ...
case FUNCT2: ...
... etc ...
}
并且可以从同一个枚举创建函数名称列表。
List<String> functionNames = Arrays.stream(Function.values())
.map(e -> e.functionName())
.collect(Collectors.toList());