1. Вирази vs інструкції
Усі конструкції в Java поділяють на дві категорії: інструкції (Statement) і вирази (Expression). Про інструкцію зазвичай кажуть, що її виконують, а про вираз — що його обчислюють. Але це не головне.
Головна відмінність між інструкцією та виразом у тому, що вираз має результат обчислення. По‑перше, цей результат має тип, а по‑друге, його можна кудись присвоїти або використати в іншому виразі.
Приклади:
| Код | Примітки |
|---|---|
|
Інструкція |
|
Вираз; тип — boolean |
|
Вираз; тип збігається з типом змінної i |
|
Вираз; тип збігається з типом змінної x |
Що це нам дає?
По‑перше, можна використати той факт, що часто те, що виглядає як інструкція, насправді є виразом (має результат обчислення). Наприклад, такий код працюватиме:
int x, y, z;
x = y = z = 1; // x = (y = (z = 1));
По‑друге, ми можемо ігнорувати результат обчислення виразу, якщо хочемо.
console.nextLine(); // ігноруємо результат введення
Це зручно, коли вираз, окрім результату, виконує ще й корисну дію, і нам важлива саме вона, а не результат.
2. Тернарний оператор
Цей лайфхак уже цікавіший за попередній. У Java є спеціальний тернарний (потрійний) оператор. Він подібний до скороченого запису оператора if-else:
Умова ? Вираз1 : Вираз2;
Якщо умова істинна, виконується вираз1; інакше — вираз2. Після умови — знак питання, а два вирази розділені двокрапкою.
Головна відмінність тернарного оператора від оператора if-else у тому, що тернарний оператор є виразом, тож його результат можна присвоїти змінній.
Наприклад, хочемо обчислити мінімум двох чисел. З використанням тернарного оператора цей код виглядатиме так:
int a = 2;
int b = 3;
int min = a < b ? a : b;
Або, скажімо, треба присвоїти змінній різні значення залежно від якогось умовного виразу. Як це зробити?
Перший варіант — скористатися оператором if-else:
int age = 25;
int money;
if (age > 30)
money = 100;
else
money = 50;
Другий варіант — використати тернарний оператор, тобто скорочений запис оператора if-else:
int age = 25;
int money = age > 30 ? 100 : 50;
Тож що ж краще використовувати: оператор if-else чи тернарний оператор? З погляду швидкодії особливої різниці немає. Справа радше в читабельності коду. І це дуже важливий момент: код має не лише правильно працювати, а й бути читабельним для інших розробників.
Найпростіший критерій може бути таким: якщо код вміщується в один рядок — користуйтеся тернарним оператором, якщо в один рядок він уже не вміщується — краще використовувати if-else.
3. Нюанси роботи
Типи значень
Важливо памʼятати: обидві гілки тернарного оператора (<значення_якщо_істина> і <значення_якщо_хиба>) мають бути одного типу або сумісними (наприклад, обидві String або обидві int).
Працює:
int a = 10, b = 20;
int max = (a > b) ? a : b; // обидві гілки — int
Помилка компіляції:
int a = 10, b = 20;
// String і int несумісні
String result = (a > b) ? "більше" : 0; // Помилка компіляції: не можна присвоїти int змінній типу String
Правильний варіант:
int a = 10, b = 20;
String result = (a > b) ? "більше" : "менше або дорівнює";
Приклад: робота з числами
Обчислимо абсолютне значення за допомогою тернарного оператора:
int number = -5;
int abs = (number >= 0) ? number : -number;
System.out.println(abs); // 5
4. Вбудовування тернарного оператора в застосунок
Давайте створимо простий діалоговий застосунок: окрім привітання, програма скаже користувачеві, скільки років йому буде через рік, і підкаже, чи буде він повнолітнім.
System.out.print("Введіть своє імʼя: ");
String name = console.nextLine();
System.out.print("Введіть свій вік: ");
int age = console.nextInt();
int nextYear = age + 1;
String status = (nextYear >= 18) ? "повнолітній" : "неповнолітній";
System.out.println("Привіт, " + name + "! Наступного року вам буде " + nextYear + ". Ви будете " + status + ".");
Пояснимо деталі:
Змінна status визначається тернарним оператором: якщо вік через рік не менший за 18, отже, користувач буде повнолітнім (або залишиться таким).
5. Вкладені тернарні оператори — обережно!
Тернарний оператор можна вкладати один у другий (у кожній гілці може бути ще один тернарний оператор). Але… від цього зазвичай болить голова, особливо в того, хто читатиме код після вас (навіть якщо це ви через 2 дні).
Приклад: визначення категорії за віком
String category = (age < 7) ? "дошкільник" :
(age < 18) ? "школяр" :
(age < 65) ? "дорослий" : "пенсіонер";
Таблиця прийняття рішення:
| Вік | Умова | Результат |
|---|---|---|
| < 7 | |
дошкільник |
| 7–17 | |
школяр |
| 18–64 | |
дорослий |
| 65 і більше | інакше | пенсіонер |
Такий код ще можна читати, але якщо логіка складніша — краще використовувати if-else if-else.
6. Лайфхак: тернарний оператор і тип boolean
Іноді хочеться написати вираз на кшталт:
boolean adult = (age >= 18) ? true : false;
Але це зайве. Сам вираз (age >= 18) уже повертає boolean. Тож можна скоротити до:
boolean adult = (age >= 18);
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ