多个if语句输出不正确

时间:2016-11-27 07:06:50

标签: java arrays enums

我想用一些枚举值填充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");
}

2 个答案:

答案 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>来处理转换。

使用流搜索有一些解释。

  1. 首先创建一个Stream枚举值
  2. 将其过滤为仅包含code与所需代码匹配的枚举值(应该只有一个)
  3. 选择第一个条目,该条目以Optional的形式返回。如果未找到任何内容(即代码无效),Optional将为空。
  4. 使用orElse方法返回值(如果存在)或ActionType.Incorrect(如果不存在)。
  5. 乍一看,这可能看起来效率低下,因为人们期望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的构造函数需要它。