我想用一些枚举值填充acts
数组。迭代时我想从控制台输入命令,但我的if语句找不到任何匹配,我总是得到输出"Incorrect"
。
我的代码:
Action[] acts = new Action[n];
for(int i = 0; i < n; i++) {
System.out.println("Enter act: ");
Scanner in1 = new Scanner(System.in);
String s = in1.next();
acts[i] = new Action();
if (s.equals("rotate_forw"))
acts[i].type = ActionType.RotF;
if (s.equals("rotate_back"))
acts[i].type = ActionType.RotB;
if (s.equals("shift_forw"))
acts[i].type = ActionType.ShiftF;
if (s.equals("shift_back"))
acts[i].type = ActionType.ShiftB;
else
System.out.println("Incorrect");
}
答案 0 :(得分:7)
您的else
子句仅适用于上一个if
语句,因此只要"Incorrect"
为s.equals("shift_back")
,您就会获得false
输出。
您的陈述应替换为单个if-else-if ...- else语句,以便只有所有条件为"Incorrect"
时才会打印false
:
Action[] acts = new Action[n];
for(int i = 0; i < n; i++) {
if (s.equals("rotate_forw"))
acts[i].type = ActionType.RotF;
else if (s.equals("rotate_back"))
acts[i].type = ActionType.RotB;
else if (s.equals("shift_forw"))
acts[i].type = ActionType.ShiftF;
else if (s.equals("shift_back"))
acts[i].type = ActionType.ShiftB;
else
System.out.println("Incorrect");
}
当输入不正确时,您还应该考虑要分配给acts[i].type
的内容。也许你应该在这种情况下抛出异常。
答案 1 :(得分:2)
虽然@Eran的答案是正确的,但我想建议一种不同的方法,用外部编码的翻译封装enum。考虑一下:
public class EnumDemo
{
public static enum ActionType
{
Incorrect(""),
RotF("rotate_forw"),
RotB("rotate_back"),
ShiftF("shift_forw"),
ShiftB("shift_back");
private String code;
private ActionType(String code)
{
this.code = code;
}
public static ActionType fromString(String code)
{
return Arrays.stream(ActionType.values())
.filter(v->v.code.equals(code))
.findFirst()
.orElse(ActionType.Incorrect);
}
}
public static void main(String[] args)
{
String[] testData = {
"rotate_forw",
"rotate_back",
"shift_forw",
"shift_back",
"junk",
null };
Arrays.stream(testData)
.forEach(t->System.out.printf("\"%s\" -> ActionType.%s\n", t, ActionType.fromString(t)));
}
}
这使用枚举常量可以具有关联数据的事实。我添加了一个实例变量code
来保存每个枚举值的外部编码。然后我在枚举中添加了一个静态fromString(String code)
方法,用于查找值列表中提供的代码。对于4种可能性,简单的线性搜索(相当于if-then-else
级联)可以正常工作。如果有几十个或更多,我会设置一个Map<String,ActionType>
来处理转换。
使用流搜索有一些解释。
Stream
枚举值code
与所需代码匹配的枚举值(应该只有一个)Optional
的形式返回。如果未找到任何内容(即代码无效),Optional
将为空。orElse
方法返回值(如果存在)或ActionType.Incorrect
(如果不存在)。乍一看,这可能看起来效率低下,因为人们期望filter()
谓词必须扫描整个流,即使所需的元素提前发生。这是Streams的一个非常好的功能 - 所有中间流都是“懒惰的”,因此如果过滤器提前找到所需的条目,则过滤器不会遍历整个列表。有关详细信息,请参阅this question。
输出:
"rotate_forw" -> ActionType.RotF
"rotate_back" -> ActionType.RotB
"shift_forw" -> ActionType.ShiftF
"shift_back" -> ActionType.ShiftB
"junk" -> ActionType.Incorrect
"null" -> ActionType.Incorrect
最后一个测试用例显示代码是空的。
最大的优点是映射与枚举本身位于同一位置,因此在添加或删除枚举值时,您无需寻找代码。你也不能忘记定义映射,因为enum的构造函数需要它。