Класс Scanner в Java

🔥 🚀 Важно для всех, кто работает с 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».

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх