1. Читання з консолі, System.in

У попередніх лекціях ми ознайомилися з командами виведення на екран. Для цього ми використовували об'єкт System.out і його методи print() і println(). Просто і зручно.

Однак, як ви вже, напевно, здогадуєтеся, самого лише виведення на екран замало. Мета більшості програм — зробити щось корисне для користувача. Тому дуже часто є потреба в тому, щоб користувач міг вводити дані з клавіатури.

Так само як для виведення, для введення даних теж є спеціальний об'єкт — System.in. Але, на жаль, він не настільки зручний, як нам хотілося б. Цей об'єкт дає змогу зчитувати дані з клавіатури по одному символу за раз.

Ось чому ми скористаємося ще одним класом, який у парі з об'єктом System.in дасть нам усе, що потрібно. У Java вже давно є класи на всі випадки життя. З одним із них ми зараз і познайомимося.


2. Клас Scanner

Клас Scanner (повне ім'я java.util.Scanner) вміє зчитувати дані з різних джерел: консолі, файлів, інтернету. Якщо ми хочемо, щоб він зчитував дані з клавіатури, ми маємо передати йому об'єкт System.in як параметр — джерело даних. А об'єкт типу Scanner вже сам розбереться, що з ним робити.

Зчитування з клавіатури за допомогою об'єкта типу Scanner матиме приблизно такий вигляд:

Код Пояснення
Scanner console = new Scanner(System.in);
String name = console.nextLine();
int age = console.nextInt();
Створюємо об'єкт класу Scanner.
Читаємо з клавіатури рядок тексту.
Читаємо з клавіатури число.

На вигляд начебто нескладно, але чи так все просто насправді?

Гадаю, у вас виникла купа запитань, і зараз ми на них відповімо.

Але спершу наведемо приклад повної програми, в якій використовується клас Scanner:

import java.util.Scanner;
public class Solution {
   public static void main(String[] args)
   {
      Scanner console = new Scanner(System.in);
      String name = console.nextLine();
      int age = console.nextInt();

      System.out.println("Name: " + name);
      System.out.println("Age: " + age);
   }
}

3. Створення об'єкта Scanner

Перше запитання — що це за рядок Scanner console = new Scanner(System.in);?

Такий рядок може збивати з пантелику, проте вам будуть постійно траплятися подібні речі. Отже, здається, настав час пояснити, що тут написано.

Згадаймо, як ми зазвичай створюємо змінну з текстом:

String str = "текст";
Оголошення та ініціалізація рядкової змінної

Спочатку ми пишемо тип змінної (String), потім її ім'я (str) і, нарешті, після знака рівності пишемо значення.

У нашому дивному рядку насправді все так само:

Scanner console = new Scanner(System.in);
Оголошення та ініціалізація змінної типу Scanner

Усе, що записано ліворуч від знака рівності, — це оголошення змінної типу Scanner з іменем console. Можна було назвати її, наприклад, s або scanner, або навіть keyboard. Тоді код мав би такий вигляд:

Scanner s = new Scanner(System.in);
String name = s.nextLine();
int age = s.nextInt();
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
int age = scanner.nextInt();
Scanner keyboard = new Scanner(System.in);
String name = keyboard.nextLine();
int age = keyboard.nextInt();

Гадаю, тепер усе стало набагато ясніше.

А от код, записаний праворуч від знака рівності, трохи складніший. Ідеться про new Scanner(System.in); Однак тут теж нічого надприродного немає.

У цьому коді ми кажемо Java-машині: створи новий об'єкт (слово new) типу Scanner і передай у нього як параметр те, звідки новостворений об'єкт Scanner братиме дані, — об'єкт System.in.

Після виконання всього цього рядка в нас з'явиться змінна з іменем console типу Scanner, за допомогою якої наша програма зможе зчитувати дані з клавіатури.


4. Виклик методів

У наведеному вище прикладі наша змінна console типу Scanner зберігала в собі посилання на об'єкт типу Scanner.

Щоб викликати методи об'єкта, на який посилається змінна, потрібно після імені змінної поставити крапку, а потім ім'я методу й параметри. Загальний вигляд цієї команди такий:

змінна.метод(параметри);
Виклик методу об'єкта, на який посилається змінна

Приклади:

System.out.println("Привіт");
System.out.println(1);

Якщо ви не плануєте передавати у функцію параметри, потрібно ставити просто порожні дужки:

змінна.метод();
Виклик методу без передавання параметрів

Приклад:

System.out.println();

5. Введення даних з консолі

Вводити дані з клавіатури, коли в нас є об'єкт типу Scanner, дуже легко.

Щоб зчитати з клавіатури рядок, потрібна команда

String str = console.nextLine();

Коли програма дійде до виконання цього рядка, вона зупиниться й очікуватиме, поки користувач уведе дані й натисне клавішу Enter. Після цього все, що ввів користувач, буде збережено в змінній str.

Щоб зчитати з клавіатури число, потрібна команда

int number = console.nextInt();

Тут усе аналогічно попередній команді. Коли програма дійде до виконання цього рядка, вона зупиниться й очікуватиме, поки користувач уведе дані й натисне клавішу Enter. Після цього все, що ввів користувач, буде перетворено на число і збережено в змінній number.

Якщо користувач увів дані, які неможливо перетворити на ціле число, виникне помилка в програмі, і вона завершиться.

Щоб зчитати з клавіатури дробове число, потрібна команда

double number = console.nextDouble();

Ця команда повністю аналогічна команді nextInt(), лише з тією різницею, що вона перевіряє, чи можна введені дані перетворити на число double.

Приклад програми, яка зчитує з клавіатури два числа й виводить їх суму:

import java.util.Scanner;
public class Solution {
   public static void main(String[] args)
   {
      Scanner console = new Scanner(System.in);
      int a = console.nextInt();
      int b = console.nextInt();

      System.out.println(a + b);
   }
}
Примітка

Користувач може ввести кілька чисел в одному рядку, розділивши їх пробілами: така ситуація буде коректно оброблена методами класу Scanner. Однак програма прочитає числа лише після того, як користувач натисне Enter.



6. Інші методи класу Scanner

Це, до речі, були не всі методи класу Scanner. Повний список матиме приблизно такий вигляд:

Метод Опис
nextByte()
Зчитує дані та перетворює їх на тип byte
nextShort()
Зчитує дані та перетворює їх на тип short
nextInt()
Зчитує дані та перетворює їх на тип int
nextLong()
Зчитує дані та перетворює їх на тип long
nextFloat()
Зчитує дані та перетворює їх на тип float
nextDouble()
Зчитує дані та перетворює їх на тип double
nextBoolean()
Зчитує дані та перетворює їх на тип boolean
next()
Зчитує одне «слово». Слова розділяються пробілами або Enter
nextLine()
Зчитує весь рядок

Крім того, є методи, які дають змогу перевірити тип іще не зчитаних даних (щоб знати, яким методом їх зчитувати).

Метод Опис
hasNextByte()
Там тип byte? Чи можна його перетворити на тип byte?
hasNextShort()
Там тип short? Чи можна його перетворити на тип short?
hasNextInt()
Там тип int? Чи можна його перетворити на тип int?
hasNextLong()
Там тип long? Чи можна його перетворити на тип long?
hasNextFloat()
Там тип float? Чи можна його перетворити на тип float?
hasNextDouble()
Там тип double? Чи можна його перетворити на тип double?
hasNextBoolean()
Там тип boolean? Чи можна його перетворити на тип boolean?
hasNext()
Там є ще одне слово?
hasNextLine()
Там є ще один рядок?

7. Введення даних з рядка

Ми вже говорили вище, що клас Scanner вміє зчитувати дані з різних джерел. І одне з цих джерел — рядок тексту.

Отакий вигляд це має:

String str = "текст";
Scanner scanner = new Scanner(str);

Замість об'єкта System.in ми під час створення об'єкта типу Scanner передаємо в нього рядок — str. І тепер об'єкт scanner буде зчитувати дані з рядка. Приклад:

Код програми: Пояснення:
import java.util.Scanner;
public class Solution {
   public static void main(String[] args)
   {
      String str = "10 20 40 60";
      Scanner scanner = new Scanner(str);
      int a = scanner.nextInt();
      int b = scanner.nextInt();

      System.out.println(a + b);
   }
}






// a == 10;
// b == 20;
На екран буде виведено: 30