Ответ 1
Обзор методов Scanner.hasNextXXX
java.util.Scanner
имеет много методов hasNextXXX
, которые могут использоваться для проверки ввода. Вот краткий обзор всех из них:
-
hasNext()
- у него есть любой токен вообще? -
hasNextLine()
- есть ли еще одна строка ввода? - Для Java-примитивов
-
hasNextInt()
- у него есть токен, который можно разобрать вint
? - Также доступны
hasNextDouble()
,hasNextFloat()
,hasNextByte()
,hasNextShort()
,hasNextLong()
иhasNextBoolean()
- В качестве бонуса также есть
hasNextBigInteger()
иhasNextBigDecimal()
- Интегральные типы также имеют перегрузки для указания оснований (например, шестнадцатеричных)
-
- Регулярное выражение
-
hasNext(String pattern)
-
hasNext(Pattern pattern)
- этоPattern.compile
перегрузка
-
Scanner
способен к большему, включенному тем, что он основан на регулярном выражении. Важной особенностью является useDelimiter(String pattern)
, которая позволяет определить, какой шаблон разделяет ваши токены. Существуют также методы find
и skip
, которые игнорируют разделители.
Следующее обсуждение будет поддерживать регулярное выражение как можно более простым, поэтому фокус остается на Scanner
.
Пример 1: Проверка положительных целых чисел
Вот простой пример использования hasNextInt()
для проверки положительного int
на входе.
Scanner sc = new Scanner(System.in);
int number;
do {
System.out.println("Please enter a positive number!");
while (!sc.hasNextInt()) {
System.out.println("That not a number!");
sc.next(); // this is important!
}
number = sc.nextInt();
} while (number <= 0);
System.out.println("Thank you! Got " + number);
Вот пример сеанса:
Введите положительное число!
пять
Это не число!
-3
Введите положительное число!
5
Спасибо! Получил 5
Заметьте, насколько проще Scanner.hasNextInt()
использовать по сравнению с более подробными try/catch
Integer.parseInt
/NumberFormatException
комбо. По контракту a Scanner
гарантирует, что если он hasNextInt()
, то nextInt()
мирно предоставит вам int
и не будет бросать никаких NumberFormatException
/InputMismatchException
/NoSuchElementException
.
Связанные вопросы
- Как использовать Scanner для принятия только действительного int в качестве входа
- Как заставить сканер отбрасывать исключения при вводе неправильного типа? (java)
Пример 2: Несколько hasNextXXX
на одном и том же токене
Обратите внимание, что вышеприведенный фрагмент содержит инструкцию sc.next()
для продвижения Scanner
до тех пор, пока не будет hasNextInt()
. Важно понимать, что ни один из методов hasNextXXX
не продвигает Scanner
мимо любого ввода!. Вы обнаружите, что если вы опустите это line из фрагмента, затем он перейдет в бесконечный цикл на недопустимом вводе!
Это имеет два следствия:
- Если вам нужно пропустить вход "мусор", который не прошел тест
hasNextXXX
, вам необходимо заранее продвинутьScanner
(например,next()
,nextLine()
,skip
и т.д.)). - Если один тест
hasNextXXX
завершился с ошибкой, вы все равно можете проверить, возможно ли этоhasNextYYY
!
Здесь приведен пример выполнения нескольких тестов hasNextXXX
.
Scanner sc = new Scanner(System.in);
while (!sc.hasNext("exit")) {
System.out.println(
sc.hasNextInt() ? "(int) " + sc.nextInt() :
sc.hasNextLong() ? "(long) " + sc.nextLong() :
sc.hasNextDouble() ? "(double) " + sc.nextDouble() :
sc.hasNextBoolean() ? "(boolean) " + sc.nextBoolean() :
"(String) " + sc.next()
);
}
Вот пример сеанса:
5
(int) 5
ложь
(boolean) false
бла
(String) blah
1.1
(двойной) 1.1
100000000000
(длинный) 100000000000
выход
Обратите внимание, что порядок испытаний имеет значение. Если a Scanner
hasNextInt()
, то это также hasNextLong()
, но это не обязательно true
наоборот. Чаще всего вы хотите сделать более конкретный тест перед более общим тестом.
Пример 3: Проверка гласных
Scanner
имеет множество расширенных функций, поддерживаемых регулярными выражениями. Вот пример его использования для проверки гласных.
Scanner sc = new Scanner(System.in);
System.out.println("Please enter a vowel, lowercase!");
while (!sc.hasNext("[aeiou]")) {
System.out.println("That not a vowel!");
sc.next();
}
String vowel = sc.next();
System.out.println("Thank you! Got " + vowel);
Вот пример сеанса:
Введите гласный, в нижнем регистре!
5
Это не гласный!
г
Это не гласный!
е
Спасибо! Получил e
В regex, как строковый литерал Java, шаблон "[aeiou]"
- это так называемый "класс символов"; он соответствует любой из букв a
, e
, i
, o
, u
. Обратите внимание, что это тривиально, чтобы сделать вышеупомянутый тест нечувствительным к регистру: просто укажите такой шаблон регулярного выражения на Scanner
.
Ссылки API
-
hasNext(String pattern)
- возвращаетtrue
, если следующий токен совпадает с шаблоном, построенным из указанной строки. -
java.util.regex.Pattern
Связанные вопросы
Ссылки
Пример 4. Использование двух Scanner
сразу
Иногда вам нужно сканировать строки за строкой, с несколькими токенами на линии. Самый простой способ сделать это - использовать два Scanner
, где второй Scanner
принимает nextLine()
из первого Scanner
в качестве входного. Вот пример:
Scanner sc = new Scanner(System.in);
System.out.println("Give me a bunch of numbers in a line (or 'exit')");
while (!sc.hasNext("exit")) {
Scanner lineSc = new Scanner(sc.nextLine());
int sum = 0;
while (lineSc.hasNextInt()) {
sum += lineSc.nextInt();
}
System.out.println("Sum is " + sum);
}
Вот пример сеанса:
Дайте мне кучу чисел в строке (или "exit" )
3 4 5
Сумма составляет 12
10 100 млн. Долларов
Сумма составляет 110
ждать, что? Сумма 0
Выход
В дополнение к Scanner(String)
constructor, также Scanner(java.io.File)
и др.
Резюме
-
Scanner
предоставляет богатый набор функций, таких какhasNextXXX
методы для проверки. - Правильное использование
hasNextXXX/nextXXX
в комбинации означает, чтоScanner
будет НИКОГДА не вывестиInputMismatchException
/NoSuchElementException
. - Всегда помните, что
hasNextXXX
не продвигаетScanner
мимо любого ввода. - Не стесняйтесь создавать несколько
Scanner
, если это необходимо. Два простыхScanner
часто лучше, чем один сложныйScanner
. - Наконец, даже если у вас нет планов использовать расширенные функции регулярного выражения, имейте в виду, какие методы основаны на регулярных выражениях, а какие нет. Любой метод
Scanner
, который принимает аргументString pattern
, основан на регулярном выражении.- Совет: простой способ превратить любой
String
в литеральный шаблон -Pattern.quote
it.
- Совет: простой способ превратить любой