🔥 🚀 Важно для всех, кто работает с Java! 🔥
На JavaRocks ты найдешь уникальные туториалы, практические задачи и редкие книги, которых не найти в свободном доступе. Присоединяйся к нашему Telegram-каналу JavaRocks — стань частью профессионального сообщества!
В этой статье обсудим класс Java Scanner. Вы можете выбрать удобный для вас формат — посмотреть видеоурок на английском языке или прочитать текстовую версию ниже.
Раньше все было проще: написал код, запустил метод main(), и вот программа уже делает то, что требуется.
Но теперь все изменится! Из этой статьи вы узнаете, как взаимодействовать с программой по-настоящему и научить ее реагировать на ваши действия!
Прежде чем приступить к разбору кода, вспомните такое устройство, как сканер. Его внутренности довольно сложны, но основная идея работы простая: он считывает данные, которые предоставляет пользователь (например, паспорт или страховой полис), и сохраняет эту информацию в памяти (например, в виде изображения).
И сегодня вы создадите свой собственный сканер! Он не сможет работать с бумажными документами, но с текстом справится без проблем 🙂 Приступим!
Класс Scanner в Java
Прежде всего, мы должны познакомиться с классом java.util.Scanner.
Его функциональность очень проста. Подобно настоящему сканеру, он считывает данные из указанного вами источника, будь то строка, файл или консоль. Затем он распознает информацию и обрабатывает ее соответствующим образом.
Вот простой пример:
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner("It matters not how strait the gate,\n" +
"How charged with punishments the scroll,\n" +
"I am the master of my fate,\n" +
"I am the captain of my soul");
String s = scanner.nextLine();
System.out.println(s);
}
}Run CodeМы создали объект scanner и указали источник данных (в даном случае это текстовая строка).
Метод nextLine() обращается к источнику данных (нашему тексту с четверостишием), находит следующую непрочитанную строку (в данном случае — первую) и возвращает ее. Затем результат выводится на консоль:
It matters not how strait the gate,
Мы можем вызвать метод nextLine() несколько раз и вывести на экран весь отрывок из стихотворения:
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner("It matters not how strait the gate,\n" +
"How charged with punishments the scroll,\n" +
"I am the master of my fate,\n" +
"I am the captain of my soul");
String s = scanner.nextLine();
System.out.println(s);
s = scanner.nextLine();
System.out.println(s);
s = scanner.nextLine();
System.out.println(s);
s = scanner.nextLine();
System.out.println(s);
}
}Run CodeКаждый раз наш сканер делает один шаг вперед и считывает следующую строку.
На экране отобразится:
It matters not how strait the gate,
How charged with punishments the scroll,
I am the master of my fate,
I am the captain of my soul
Как уже говорилось, источник данных для сканера — не обязательно строка.
Например, это может быть консоль. И вот хорошие новости: раньше мы только выводили туда данные, а теперь научимся считывать ввод с клавиатуры!
Давайте посмотрим, что еще делает класс Scanner:
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number:");
int number = sc.nextInt();
System.out.println("Thanks! You entered the number " + number);
}
}Run CodeМетод nextInt() считывает и возвращает введенное значение. В нашем примере он используется для присваивания значения переменной number.
Программа уже больше похожа на настоящий сканер! Она просит пользователя ввести любое число, затем программа благодарит его, выводит результат и завершает работу.
Но у нас все еще есть серьезная проблема. Пользователь может ошибиться и ввести что-то не то.
Вот пример, при котором текущая версия программы перестает работать:
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number:");
int number = sc.nextInt();
System.out.println("Thanks! You entered the number " + number);
}
}Run CodeПопробуем вместо числа ввести строку "CodeGym".
Консольный вывод:
Enter a number:
CodeGym
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at Main.main(Main.java:10) Process finished with exit code 1
Чтобы избежать подобных ситуаций, нужно как-то проверять данные, которые вводит пользователь. Например, если пользователь вводит не число, а что-то другое, неплохо было бы вывести предупреждение о том, что введенная информация является некорректной. А если все в порядке — подтвердить, что число принято.
Но для этого требуется “заглянуть в будущее”, чтобы увидеть, что будет в потоке ввода. Может ли Scanner сделать это?
Еще как! У него есть целый набор методов для таких случаев:
hasNextInt() — проверяет, является ли следующий фрагмент ввода числом. Возвращает true или false.
hasNextLine() — проверяет, есть ли следующая строка во входных данных.
hasNextByte(), hasNextShort(), hasNextLong(), hasNextFloat(), hasNextDouble() делают то же самое, только для других типов данных.
Давайте попробуем изменить нашу программу чтения чисел:
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number:");
if (sc.hasNextInt()) {
int number = sc.nextInt();
System.out.println("Thanks! You entered the number " + number);
} else {
System.out.println("Sorry, but this is clearly not a number. Restart the program and try again!");
}
}
}Run CodeТеперь программа проверяет, является ли следующий введенный символ числом. И подтверждение выводится только в этом случае. Если введенное значение не проходит проверку — программа сообщает об этом и предлагает попробовать снова.
В принципе, вы можете “пообщаться” с объектом Scanner и заранее узнать, с каким типом данных сейчас столкнетесь. Это число? Строка? Или что-то еще? Если число — то какое? int, short, long?
Такая гибкость дает возможность выстраивать логику программы, ориентируясь на поведение пользователя. Следует отметить еще один важный метод — useDelimiter().
С помощью этого метода можно указать строку с символами-разделителями (делимитерами), по которым Scanner будет разбивать входные данные. Допустим, мы внезапно заинтересовались японской поэзией и решили использовать наш сканер для чтения хайку, написанных великим поэтом Мацуо Басё.
Даже если три стихотворения будут переданы одной длинной строкой, мы все равно сможем легко разделить их и красиво вывести на экран:
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner("On a withered branch'" +
"A crow has alighted.'" +
"Nightfall in autumn." +
"''***''" +
"Such a moon above,'" +
"Like a tree cut at the root:'" +
"he fresh cut is white." +
"''***''" +
"How the river floods!'" +
"A heron wanders on short legs,'" +
"Knee-deep in the water.");
scan.useDelimiter("'");
while (scan.hasNext()) {
System.out.println(scan.next());
}
scan.close();
}
}Run CodeВ качестве разделителя мы используем "\n/*/*/*" — символ новой строки и три звездочки.
В результате мы получаем красивый вывод в консоль, почти как в книгах:
On a withered branch
A crow has alighted.
Nightfall in autumn.
***
Such a moon above,
Like a tree cut at the root:
The fresh cut is white.
***
How the river floods!
A heron wanders on short legs,
Knee-deep in the water.
В этом примере есть еще один метод, на который мы обязательно должны обратить внимание — close(). Как и любой объект, работающий с потоками ввода-вывода, сканер нужно закрывать по завершении работы, чтобы он не потреблял ресурсы компьютера. Никогда не забывайте о методе close()!
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number:");
int number = sc.nextInt();
System.out.println("Thanks! You entered the number " + number);
sc.close(); // Now we've done everything right!
}
}Run CodeВот и все! Как видите, несмотря на свою полезность, класс Scanner очень прост в использовании! 🙂
Перевод статьи «Java Scanner Class».
