Как выйти из цикла после того, как вход был проверен для каждого элемента в перечислении Java? - PullRequest
0 голосов
/ 01 декабря 2018

Я пытаюсь создать программу, которая позволит пользователю вводить имя или символ элемента из периодической таблицы, а затем выводит некоторые данные об этом элементе.До сих пор мне удавалось заставить пользователя иметь возможность вводить либо имя, либо символ и правильно выводить его, но если пользователь вводит что-то неправильное, код ничего не выводит и перестает принимать вводсимвол и принять только ввод имени.Я хотел бы знать, как я мог бы выйти из цикла и сказать пользователю, что его ввод недействителен только после того, как вход был проверен по каждому элементу в перечислении, поскольку мое текущее решение не работает.Я новичок в 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);
    }
}

Ответы [ 4 ]

0 голосов
/ 01 декабря 2018

Вы усложняете код, смешивая поиск по имени и поиск по символу.Поиск по имени не обязательно должен быть внутри цикла 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();
}
0 голосов
/ 01 декабря 2018

Если я правильно понял, вы хотите просмотреть перечисления и посмотреть, соответствует ли какой-либо из символов введенному пользователем.Если нет, распечатайте сообщение и попробуйте снова.У вас был правильный подход, но в блоке 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
0 голосов
/ 01 декабря 2018

Я бы не использовал метод 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, и вы больше не сможете читать ввод.

0 голосов
/ 01 декабря 2018

Предполагая, что я понимаю ваш вопрос, я бы добавил логику для разбора 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

И если e было null, то это недопустимый символ (или имя).

...