JavaRush /Курси /Java Syntax Zero /Лайфхаки: як писати код краще та швидше

Лайфхаки: як писати код краще та швидше

Java Syntax Zero
Рівень 3 , Лекція 7
Відкрита

1. Вирази й команди

Усі команди в Java поділяються на дві категорії: команди (Statement) і вирази (Expression). Про команду зазвичай говорять, що вона виконується, а про вираз — що він обчислюється. Проте це не головне.

Основна відмінність між командою та виразом полягає в тому, що вираз має результат обчислення. І цей результат, по-перше, має тип, а по-друге, його можна присвоїти якомусь об'єкту або використати в якомусь іншому виразі.

Приклади:

Код Примітки
int x; Команда
(a < 10) Вираз, тип boolean
i++; Вираз, тип збігається з типом змінної i
x = 5; Вираз, тип збігається з типом змінної x

І що це нам дає?

По-перше, ми можемо скористатися тим фактом, що дуже багато команд насправді є виразами (мають результат обчислення). Наприклад, такий код працюватиме:

Код Примітки
int x, y, z;
x = y = z = 1;
int x, y, z;
x = (y = (z = 1));

По-друге, ми можемо ігнорувати результат обчислення виразу, якщо хочемо.

Код Код, в якому ми ігноруємо результат:
int x = scanner.nextInt();
boolean m = (5 < 10);
scanner.nextInt();
(5 < 10);

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


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. Порівняння дійсних чисел

Раніше ми вже говорили, що просто так порівнювати дійсні числа не можна: у процесі роботи з ними завжди можуть виникати несподівані ефекти через те, що частина значущих цифр відкидається.

Отож існує перевірений часом підхід. Якщо два дійсних числа відрізняються на дуже мале значення, їх можна вважати рівними. Приклад:

double a = 1.000001;
double b = 1.000002;
if ( (b - a) < 0.0001 )
   System.out.println("Числа рівні");
else
   System.out.println("Числа не рівні");

Але це ще не все: різниця чисел цілком може виявитися від'ємним числом. Отже, для того, щоб такий підхід працював, потрібно порівнювати не просто різницю чисел, а модуль різниці чисел: |a-b|

У Java є спеціальний метод для обчислення модуля числа — Math.abs():

int m = Math.abs(значення);

Тому виправлений варіант наведеного вище прикладу матиме ось такий вигляд:

double a = 1.000001;
double b = 1.000002;

if ( Math.abs(b - a) < 0.0001 )
   System.out.println("Числа рівні");
else
   System.out.println("Числа не рівні");

Коментарі (20)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Alya Kasta Рівень 8
5 березня 2025
Теж стикнулась з проблемою в останньому завданні, може комусь буде корисне моє пояснення чому if(Math.abs(b - a) < 0.000001) вірно а if(Math.abs(b - a) == 0) не вірно В частині Math.abs(b - a) - обчислює модуль різниці між числами Значення 0.000001 - це поріг точності для порівняння double Отже, якщо різниця чисел b - a менша за поріг точності 0.000001 то числа вважаються рівними
Іван Рівень 8
7 листопада 2024
Написав так "... if (Math.abs(firstDouble-secondDouble) < 0.000001); { ..." зарахувало помилку, тому що після виразу не треба було ставити крапку з комою, а відразу фігурну дужку..., поки я до тямив - пройшло десь 3 хвилини🤪
Михайло Рівень 4
16 серпня 2024
я теж не можу зрозуміти чого треба писати так: if (Math.abs(s - f) < 0.000001) { System.out.println("числа рівні"); } else { System.out.println("числа не рівні"); а не замінити на: if (s - f == 0)
hidden #3500645 Рівень 30
22 листопада 2024
При порівнянні дійсних чисел (типів float або double) у Java використовують віднімання змінних і перевіряють, чи різниця менша за певний поріг (так званий epsilon, тобто модуль різниці), тому що дійсні числа в пам’яті комп'ютера представляються з кінцевою точністю. Через обмеження формату з плаваючою комою в IEEE 754 можуть виникати помилки округлення, які унеможливлюють точне порівняння дійсних чисел. Основні причини: 1. Обмежена точність представлення чисел: Наприклад, число 0.1 не може бути представлено точно в двійковій системі, тому арифметичні операції з ним можуть призводити до накопичення похибок. 2. Похибки обчислень: При виконанні операцій, таких як ділення, множення або віднімання, похибки округлення накопичуються, і результат може трохи відрізнятися від очікуваного. 3. Формат IEEE 754: Це стандарт для представлення чисел з плаваючою комою, але через кінцеву кількість бітів, відведених для мантиси та експоненти, зберігається лише наближене значення числа.
hidden #3500645 Рівень 30
22 листопада 2024
Як це працює: Використовується поріг epsilon (ε), який є дуже малим числом. Замість того щоб перевіряти рівність чисел a і b через a == b, обчислюють модуль їх різниці і перевіряють, чи вона менша за epsilon:

if (Math.abs(a - b) < epsilon) {
    // Числа вважаються рівними
}
Приклад:

public class FloatComparison {
    public static void main(String[] args) {
        double a = 0.1 + 0.2; // Очікуємо 0.3
        double b = 0.3;

        // Порівняння з epsilon
        double epsilon = 1e-9;
        if (Math.abs(a - b) < epsilon) {
            System.out.println("a і b рівні");
        } else {
            System.out.println("a і b НЕ рівні");
        }
    }
}

У цьому прикладі 0.1 + 0.2 не дорівнює точно 0.3 через похибки округлення, тому порівняння через == поверне false. Використання epsilon допоможе правильно оцінити, що ці числа достатньо близькі для вважання їх рівними.
Anonymous #3398391 Рівень 4
27 лютого 2024
Не знаю, що там люди не розуміють в останньому завданні, але я написав свій код

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		System.out.print("Введіть число a: ");
		double a = s.nextDouble();
		System.out.print("Введіть число b: ");
		double b = s.nextDouble();
		System.out.println((a > b)? "a > b" : "a < b");		
	}
}
15 жовтня 2023
Написав "Числа не рівні" з великої, зарахувало як помилку)
Владислав Рівень 6
9 липня 2023
Не розумію чому треба вказувати діапазон чому просто не можна написати if ( x == y)... , де x та y дійсні числа. Хто пояснить, буду вдячним
Timmofeii Рівень 9
3 вересня 2023
Приветсвую. это для того чтобы понимать "важную" часть числа и то на что можно закрыть "глаза" если пользоловаться if ( x == y) то у тебя Х должно полностью совпадать с У то есть 1==1 правда будет, а 1.01=1 будет false, а в случае возможности еонмортного учитывания погрешности привели данный пример. надеюсь смог обьяснить😅
Polyhedal Рівень 3
2 вересня 2022
Почему System.out.println(numberA > numberB ? numberA : numberB); и int max = numberA > numberB ? System.out.println(numberA) : System.out.println(numberB); не одно и то же? В лекции тернарный оператор показывается через переменную инт, а код не пропускает такой.
Igor Рівень 6
10 вересня 2022
Аналогичный вопрос
Savichon Рівень 17
15 вересня 2022
В 2 варіанті ти прирівнюєш до змінної int max вираз System.out.println(), тому і не вірно
Ivanka K Рівень 3
23 вересня 2022
мій варіант теж інший, ніби коротший: int max = numberA > numberB ? numberA : numberB; System.out.println(max);
Ivanka K Рівень 3
23 вересня 2022
думаю, що System.out.println - це команда, а оператор працює з виразами тобто int max можна присвоїти значення виразу, а це значення береться з вибору двох значень, а не двох команд, тобто тернарний оператор для присвоєння значень через вибір, а не для вибору команд
Ivanka K Рівень 3
23 вересня 2022
тобто чинаючи вашу умову в такому вигляді я розумію таке: цілому числу з іменем мах присвоїти значення числа при умові, якщо numberA > numberB ? і тут програма очікує на число типу int і ми маємо дати їй 2 такі варіанти а Ви даєте 2 команди, причому для виводу в консоль, а вона хоче просто 2 варіанти чисел для вибору виходить що в цьому разі int max нічого не присвоєно
Roma Chernesh Рівень 16
20 листопада 2022
у прикладі з лекції нічого не виводили на екран. тут задачка була на логіку (ну, чи перевірка, хоча б загуглиш ти чі ні) У цьому випадку не можна записати у зміну max типу int значення System.out.println(...) Тобто ще раз: System.out.println(numberA > numberB ? numberA : numberB); тут ми виводимо на екран значення змінної типу int а у твоєму коді: int max = numberA > numberB ? System.out.println(numberA) у змінну типу int призначають не цифру, а команду, що виводить текст у консоль (що не подобається компілятору, бо Java так не працює)
kora Рівень 6
13 липня 2022
в последнем задании тяжко было 🤯
Polyhedal Рівень 3
2 вересня 2022
переписать пример, добавив нули? 🤔😬
Oleksii Klym Рівень 11
6 жовтня 2022
звідки ти знаєш, що він саме про нулі??? до прикладу, я не міг зрозуміти в чому проблема, так як в коді ти пишеш крапку. А от чому в консолі ти повинен писати кому замість крапки не зрозуміло.... але раз так працює то нехай
Maxim Рівень 6
3 червня 2023
та ні, все дуже легко