【问题标题】:Switch statement using substring of a user's input使用用户输入的子字符串切换语句
【发布时间】:2019-05-27 21:56:14
【问题描述】:

目标:我正在尝试根据用户的输入输出一条消息。

情况:基本上用户会输入几个字符,例如 5r(5 Red)或 8y(8 Yellow)。预期的符号是先有数字,后有字符,但用户可能不遵守规则。

我使用了 switch 语句(练习的一部分),但输出没有给我预期的结果

代码

        String input = reader.nextLine().toLowerCase();
        String firstChar = input.substring(0,1);
        String secondChar = input.substring(1);
        String answer = "";

        switch(firstChar)
        {
            case "0":
            {
                switch(secondChar)
                {
                    case "b":
                        answer = "Zero Blue";
                    case "r":
                        answer = "Zero Red";
                    case "g":
                        answer = "Zero Green";
                    case "y":
                        answer = "Zero Yellow";
                }
            }
            case "1":
            {
                switch(secondChar)
                {
                    case "b":
                        answer = "One Blue";
                    case "r":
                        answer = "One Red";
                    case "g":
                        answer = "One Green";
                    case "y":
                        answer = "One Yellow";
                }
            }
           ... other case statements....
           default:
              answer = "not valid";

当用户写入 0b 时,我的输出应该是“零蓝”,但目前它显示的是“无效”。为什么?

【问题讨论】:

  • 您忘记在每个case 之间添加break; 语句。
  • ... @markspace 那是一个愚蠢的。谢谢你。我需要为每个 case 语句加上大括号来包含 break 和语句吗?
  • 不,即使里面有多个元素,case 语句也不需要大括号。阅读我的更新答案,了解有关 switch 语句以及使用数组的可行代码的更多信息。

标签: java loops switch-statement


【解决方案1】:

正如@markspace 提到的,您缺少一个 break 语句。以下是 Java documentation 关于 switch 语句的简短摘录:

每个 break 语句都会终止封闭的 switch 语句。控制流继续 switch 块之后的第一条语句。 break 语句是必要的,因为没有它们,switch 块中的语句就会失败。

我还建议使用专用方法和for 循环以便于调试。

下面的代码会产生你想要的结果:

public static String getAnswer() {

        Scanner reader = new Scanner(System.in);
        String input = reader.nextLine().toLowerCase();
        String firstChar = input.substring(0, 1);
        String secondChar = input.substring(1);

        String[] chars = new String[] { "b", "r", "g", "y" };
        String[] answers1 = new String[] { "Zero Blue", "Zero Red", "Zero Green", "Zero Yellow" };
        String[] answers2 = new String[] { "One Blue", "One Red", "One Green", "One Yellow" };

        if ((firstChar.equals("0"))) {
            for (int i = 0; i < chars.length; i++) {
                if (secondChar.equals(chars[i])) {
                    return answers1[i];
                }
            }
        }
        else if ((firstChar.equals("1"))) {
            for (int i = 0; i < chars.length; i++) {
                if (secondChar.equals(chars[i])) {
                    return answers2[i];
                }
            }
        }
        return "not valid";
    }

    public static void main(String[] args) throws IOException {

        System.out.println(getAnswer());
    }

编辑:除了上面的解决方案,我想提供一个更复杂的解决方案,它涉及使用枚举器。它应该让你的代码感觉更干净、更切题,并且更模块化:

public enum Answer {

    BLUE('b',"Blue"), RED('r',"Red"),
    GREEN('g',"Green"), YELLOW('y',"Yellow");

    private static final String[] prefix = new String[] {"Zero", "One"};

    char letter;
    String name;

    Answer(char letter, String name) {
        this.letter = letter;
        this.name = name;
    }

    public static String getForInput(char input, int index) {

        if (index > prefix.length)
            return "value out of range " + index;

        for (Answer answer : Answer.values()) {
            if (input == answer.letter)
                return prefix[index] + " " + answer.name;
        }
        return "unable to find answer for input " + input;
    }
}

public static String getAnswer() {

    System.out.println("Enter your input: ");
    Scanner reader = new Scanner(System.in);
    String input = reader.nextLine().toLowerCase();
    int number = Integer.valueOf(input.substring(0, 1));
    char letter = input.substring(1).charAt(0);

    return Answer.getForInput(letter, number);

}

【讨论】:

    【解决方案2】:

    我建议根本不使用 swich case,使用哈希映射:

    package mypackage;
    
    import java.util.*;
    
    public class MyComputingClass {
    
        private static Map<Character, String> firstCharMapping;
        private static Map<Character, String> secondCharMapping;
    
        public static void main(String[] args) {
            initCharMappers();
    
            System.out.println("Mapping of 0Y : " + mapStuff("0Y"));
            System.out.println("Mapping of 0y : " + mapStuff("0y"));
            System.out.println("Mapping of 0YJ : " + mapStuff("0YJ"));
            System.out.println("Mapping of 2B : " + mapStuff("2B"));
            System.out.println("Mapping of eB : " + mapStuff("eB"));
        }
    
        private static void initCharMappers() {
            firstCharMapping = new HashMap<>();
            secondCharMapping = new TreeMap<>(Comparator.comparing(Character::toLowerCase));
    
            firstCharMapping.put('0', "Zero");
            firstCharMapping.put('1', "One");
            firstCharMapping.put('2', "Two");
    
            secondCharMapping.put('Y', "Yellow");
            secondCharMapping.put('B', "Blue");
            secondCharMapping.put('G', "Green");
        }
    
        private static String mapStuff(String str) {
            String INVALID_INPUT = "Invalid input";
            if (!str.matches("\\d[a-zA-Z]")) {
                return INVALID_INPUT;
            }
    
            Character firstChar = str.toCharArray()[0];
            Character secondChar = str.toCharArray()[1];
    
            if (!firstCharMapping.containsKey(firstChar) || !secondCharMapping.containsKey(secondChar)) {
                return INVALID_INPUT;
            }
    
            return firstCharMapping.get(firstChar) + " " + secondCharMapping.get(secondChar);
        }
    }
    

    输出:

    Mapping of 0Y : Zero Yellow
    Mapping of 0y : Zero Yellow
    Mapping of 0YJ : Invalid input
    Mapping of 2B : Two Blue
    Mapping of eB : Invalid input
    

    【讨论】:

      猜你喜欢
      • 2017-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多