如何将Java中的开关替换为每个情况引用一个变量的列表?
How can I replace a switch in Java with a list that references a variable for each case?
我在这里找不到这样的问题(这让我很惊讶),所以…
我有一个工作的Java程序,其中一部分分析键入的输入。一些输入'选项'是以下情况下的字符串。
switch (varName.toLowerCase()) {
case "steps":
common.steps = true;
break;
case "scale":
common.scale = true;
break;
case "float":
common.fracts = false;
break;
case "fraction":
common.fracts = true;
break;
case "spaces":
common.spaces = false;
break;
... etc.
}
在C或c++中,我可以通过创建一个列表(这是一个包含字符串名称和变量指针的结构)来缩短代码,例如
LIST varAction[] = { { "steps", &common.steps },
{ "scale", &common.scale },
.. etc.
};
,然后在I = 0的循环中检查列表
的大小。if ( strcmp(varAction[i].name, input) == 0) {
*varAction[i].pointer = condition;
}
Java切换不止一次,这是一个维护问题,这就是为什么我想要一个更好的方法。
我可以使用字符串的哈希值对数组使用哈希索引,但这会阻止我根据需要在代码中使用特定的变量名,使代码不太清楚……例如,我不想做(伪代码)
hashTable[varName] instead of (for example)
if ( common.fracts )
{ do something }
一定有更好的办法吧?是吗?
从你的问题中,很明显你知道你不能做你说过你在C/c++中会做的事情,但只是为了其他人来问这个问题:Java没有对变量的引用。
很容易把这个问题推到一个层次:首先看看为什么你有varName
,看看你是否可以避免它。
Java切换不止一次,这是一个维护问题,这就是为什么我想要一个更好的方法。
这表明common
应该有这个信息的访问函数,所以开关只存在于一个地方(getter)或两个地方(getter和setter)。
void setThingy(String name, boolean value) {
switch (name.toLowerCase()) {
case "steps":
this.steps = value;
break;
case "scale":
this.scale = value;
break;
case "float":
this.fracts = value;
break;
case "fraction":
this.fracts = value;
break;
case "spaces":
this.spaces = value;
break;
// ... etc.
}
}
boolean getThingy(String name) {
switch (name.toLowerCase()) {
case "steps":
return common.steps;
case "scale":
return common.scale;
case "float":
return this.fracts;
case "fraction":
return this.fracts;
case "spaces":
return this.spaces;
// ... etc.
}
}
如果common
的类不是你可以改变的东西,一个静态的实用函数也会在某个地方工作,但如果可能的话,如果它在类中更好。
对于Java 8+,您可以使用如下命令:
Map<String, Runnable> actions = new HashMap<> ();
actions.put("steps", () -> common.steps = true);
actions.put("scale", () -> common.scales = true);
//etc.
然后在你的代码中:
actions.get(varName.toLowerCase()).run(); //need null check
你也可以在Java 7中使用匿名类,但是会更冗长。
这是一个选项,从评论中发展我的想法只是一点点。我不确定你是否会喜欢,但我想提供给你,以防万一。
public class Common {
private Map<String, Boolean> options = new HashMap<>();
public void setOption(String varName, boolean condition) {
options.put(varName.toLowerCase(), condition);
}
public boolean isSteps() { return options.get("steps"); }
public boolean isFracts() { return options.get("fractions"); }
public boolean isScale() { return options.get("scale"); }
}
您可能需要添加一些防御,例如避免设置不存在的选项。
编辑:根据David Foerster对枚举的评论,这里有一个使用枚举的解决方案:
public enum Option {
steps, scale, fraction;
private boolean option = false;
public static void setOption(String varName, boolean condition) {
valueOf(varName.toLowerCase()).option = condition;
}
public boolean isSet() {
return option;
}
}
现在查找发生在setter中,而不是getter中。防止设置不存在的选项是内置的:如果你尝试,你会得到一个异常,当然,如果你愿意,这种行为可以被修改。该解决方案具有很强的可扩展性,如果需要,可以很容易地添加更多的enum常量。
警告:距离我上次编写Java已经有一段时间了,这可能违反了最佳实践,所以请继续小心!这只是一个简单的例子,我在一个(不是最新的)手机上写的…
你可以尝试使用反射:
class Common {
public boolean a;
public boolean b;
public boolean tryToSet(String field, boolean value) throws java.lang.Exception {
Class<?> cl = this.getClass();
try {
Field f = cl.getDeclaredField(field);
f.setBoolean(this, value);
return true;
} catch(NoSuchFieldException e) {
return false;
}
}
}
返回一个布尔值让你有可能实现一个"默认情况":
if (! c.tryToSet("x", false)) {
System.out.println("some default case");
}
试试这个:
import java.util.Scanner;
public class TestCases
{
static boolean steps = false;
static boolean fracts;
static boolean scale;
public static void main( String[] args )
{
Scanner input = new Scanner( System.in );
System.out.println( "Type the input" );
String typedInput = input.nextLine();
Object[][] tests = { { "steps", steps }, { "float", fracts }, { "scale", scale } };
for( int i = 0; i < tests.length; i++ )
{
if( typedInput.equals( tests[ i ][ 0 ] ) )
{
tests[ i ][ 1 ] = true;
break;
}
}
for( int i = 0; i < tests.length; i++ )
{
for( int j = 0; j < tests[ i ].length; j++ )
{
System.out.print( tests[ i ][ j ] + " " );
}
System.out.println();
}
}
}
所有必要的转换都自动完成。
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 多个"常量引用"变量可以共享同一个内存吗?
- 在 gtest 中初始化堆栈上的引用变量的隔离错误
- C++方法中的引用变量
- 作为赋值(增加引用变量)C++的左操作数所需的左值
- 使用更改此变量的函数在同一行中打印引用变量
- 将延迟变量分配给引用变量
- 如何通过引用获取引用变量的地址?
- 将引用变量传递给函数
- C++中引用变量的内存?
- 按名称存储和引用变量列表
- 返回一个C++引用变量 VS 返回一个变量
- c++ 在 if 语句中分配引用变量
- 引用变量何时合适,为什么?你能解释一下实际的语法和位置吗?
- C++ - 将一个变量分配给另一个变量和将变量分配给引用变量有什么区别?
- 在类范围内声明时,应在 C++14 中引用变量模板
- 当引用变量的引用"死亡"时,它会发生什么?
- 将非按引用变量分配给返回按引用的函数,反之亦然
- 引用变量如何存储在mem中
- 引用变量存储在哪里