在针对枚举 Java 中的每个项目检查输入后如何跳出循环?

How to break out of a loop after an input has been checked against every item in an enum Java?

我正在尝试编写一个程序,允许用户输入周期性 table 中元素的名称或符号,然后输出有关该元素的一些数据。到目前为止,我已经设法让用户能够输入名称或符号并正确输出,但如果用户输入错误,则代码不会输出任何内容,并将停止接受输入一个符号,只接受名称的输入。我想知道如何才能跳出循环并告诉用户他们的输入仅在针对枚举中的每个项目检查输入后才无效,因为我当前的解决方案不起作用。我是 Java 的新手,所以我将不胜感激关于如何以及为什么的简单解释。

import java.util.Scanner;
public class PeriodicTable {

    public enum Element {
        Hydrogen("H", "Nonmetal", "1.008"),
        Helium("He", "Noble Gas", "4.003"),
        Lithium("Li", "Alkali Metal", "6.941"),
        Beryllium("Be", "Alkaline Earth", "9.012"),
        Boron("B", "Semimetal", "10.811"),
        Carbon("C", "Nonmetal", "12.011"),
        //The rest of the periodic table is here, I just removed it for the sake of this post.

        private String symbol;
        private String group;
        private String weight;

        private Element(String symbol, String group, String weight) {
            this.symbol = symbol;
            this.group = group;
            this.weight = weight;
        }
    }

    static Element cName = null;
    public static void main(String[] args) {

        int counter = 0;
        System.out.println("Enter the name or symbol of an element in the periodic table. ");
        outer:
        do {
            Scanner reader = new Scanner(System.in);
            String input = reader.nextLine().trim();
            for (Element sy : Element.values()) {
                if (sy.symbol.equalsIgnoreCase(input)) {
                    System.out.println("Element: " + sy + " (" + sy.symbol + ")" + "\nGroup: " + sy.group + "\nAtomic Mass: " + sy.weight);
                    reader.close();
                    break outer;
                } else {
                    try {
                        cName = Element.valueOf(input.substring(0, 1).toUpperCase() + input.substring(1).toLowerCase());
                        System.out.println("Element: " + cName + " (" + cName.symbol + ")" + "\nGroup: " + cName.group + "\nAtomic Mass: " + cName.weight);
                        reader.close();
                        break outer;
                    } catch(IllegalArgumentException e) {
                        if(counter > Element.values().length) {
                            System.out.println("That name or symbol is not valid. Please try again. ");
                            continue outer;
                        } else {
                            counter++;
                            continue;
                        }
                    }
                }
            }
        } while (true);
    }
}

假设我理解你的问题,我会将解析 Element(s) 的逻辑添加到 Element。您可以创建 Map(s),一个用于符号,一个用于相应的 Element 实例,然后以您选择的顺序调用它们。喜欢,

private static Map<String, Element> symbolMap = new HashMap<>();
private static Map<String, Element> nameMap = new HashMap<>();
static {
    for (Element e : Element.values()) {
        symbolMap.put(e.symbol.toUpperCase(), e);
        nameMap.put(e.name().toUpperCase(), e);
    }
}

public static Element fromString(String token) {
    if (symbolMap.containsKey(token.toUpperCase())) {
        return symbolMap.get(token.toUpperCase());
    }
    return nameMap.get(token.toUpperCase());
}

然后在main

Element e = Element.fromString("H"); 
Element e2 = Element.fromString("Hydrogen");
System.out.println(e == e2); // <-- true

如果 enull 那么它不是一个有效的符号(或名称)。

如果我没理解错的话,你想查看枚举并查看是否有任何符号与用户输入匹配。如果没有,请打印一条消息并重试。你有正确的方法,但在 catch 块中你不需要进行计数器。相反,如果我们仔细考虑设计,如果输入匹配,您将获得 break outer;。所以只有在没有匹配元素的情况下,do-while 循环才会结束。因此,如果我们只在最后打印一条消息,这将实现我们的目标:

outer:
do {
    Scanner reader = new Scanner(System.in);
    String input = reader.nextLine().trim();
    for (Element sy : Element.values()) {
        if (sy.symbol.equalsIgnoreCase(input)) {
            System.out.println("Element: " + sy + " (" + sy.symbol + ")" + "\nGroup: " + sy.group + "\nAtomic Mass: " + sy.weight);
            reader.close();
            break outer;
        } else {
            try {
                cName = Element.valueOf(input.substring(0, 1).toUpperCase() + input.substring(1).toLowerCase());
                System.out.println("Element: " + cName + " (" + cName.symbol + ")" + "\nGroup: " + cName.group + "\nAtomic Mass: " + cName.weight);
                reader.close();
                break outer;
            } catch(IllegalArgumentException e) {
                continue;
            }
        }
    }
    System.out.println("Error. No matching elements. Please try again.");
} while (true);

示例输出:

Enter the name or symbol of an element in the periodic table. 
No
Error. No matching elements. Please try again.
l
Error. No matching elements. Please try again.
He
Element: Helium (He)
Group: Noble Gas
Atomic Mass: 4.003

我会避免在循环中使用 valueOf 方法。相反,您可以遍历元素并为每个元素检查其名称(使用 name 方法)及其符号。

Scanner reader = new Scanner(System.in);
outer: while (true) {
    System.out.println("Enter the name or symbol of an element in the periodic table. ");
    String input = reader.nextLine().trim();
    for (Element sy : Element.values()) {
        if (sy.symbol.equalsIgnoreCase(input) || sy.name().equalsIgnoreCase(input)) {
            System.out.println("Element: " + sy + " (" + sy.symbol + ")" + "\nGroup: " + sy.group + "\nAtomic Mass: " + sy.weight);
            break outer;
        }
    }
    System.out.println("No such element found. ");
}
reader.close(); // this might be a bad idea

我也会避免关闭 reader,因为这也会关闭 System.in,您将无法再阅读任何输入。

您通过混合搜索名称和搜索符号来使代码复杂化。
搜索名称不需要在 for 循环内:

public static void main(String[] args) {
    Scanner reader = new Scanner(System.in);
    System.out.println("Enter the name or symbol of an element in the periodic table. ");
    boolean found = false;
    do {
        String input = reader.nextLine().trim();

        try {
            cName = Element.valueOf(input.substring(0, 1).toUpperCase() + input.substring(1).toLowerCase());
            System.out.println("Element: " + cName + " (" + cName.symbol + ")" + "\nGroup: " + cName.group + "\nAtomic Mass: " + cName.weight);
            found = true;
        } catch (IllegalArgumentException e) {
        }

        for (Element sy : Element.values()) {
            if (sy.symbol.equalsIgnoreCase(input)) {
                found = true;
                System.out.println("Element: " + sy + " (" + sy.symbol + ")" + "\nGroup: " + sy.group + "\nAtomic Mass: " + sy.weight);
            }
        }

        if (!found)
            System.out.println("That name or symbol is not valid. Please try again. ");
    } while (!found);
    reader.close();
}