JavaRush /Курси /Kotlin SELF /Логічний тип Boolean і логічні операції

Логічний тип Boolean і логічні операції

Kotlin SELF
Рівень 3 , Лекція 3
Відкрита

1. Логічний тип даних: Boolean

Як ми вже переконалися, у Kotlin є дуже корисний оператор — if-else. Він виконує один блок команд, якщо умова в дужках істинна, і другий блок команд — якщо умова хибна.

Щоб було зручно працювати з виразами, які можуть бути істинними або хибними, у Kotlin додали спеціальний тип — Boolean. Його головна особливість у тому, що змінні цього типу можуть набувати лише двох значень: true (істина) і false (хиба).

Жодних інших значень присвоїти змінним типу Boolean неможливо. Компілятор цього не дозволить.

Приклади змінних типу Boolean:

val isAdult: Boolean = true
val hasMoney: Boolean = false

Змінна типу Boolean має лише два значення — true (істина) і false (хиба). Усе! Майже як у тесті: або «пройшов», або «не пройшов».

2. Операції порівняння

І навіщо ж потрібен такий примітивний тип? Справжня потужність Boolean проявляється тоді, коли ми будуємо логічні вирази. Зазвичай їх складають за допомогою операторів порівняння.

Оператор Призначення Приклад Значення
==
Дорівнює
a == b
true або false
!=
Не дорівнює
a != b
true або false
>
Більше
a > b
true або false
<
Менше
a < b
true або false
>=
Більше або дорівнює
a >= b
true або false
<=
Менше або дорівнює
a <= b
true або false

Приклад:

val age = 20
val isAdult = age >= 18               	// true (20 більше або дорівнює 18)
val isTeenager = age >= 13 && age < 18 	// false (20 не менше 18)
val isEven = age % 2 == 0             	// true (20 ділиться на 2 без остачі)

isAdult тут стане true, тому що 20 — це справді «дорослий» вік.

Важливий момент 1:

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

a < = 10
speed > = max
age = = 18
time ! = 0

Важливий момент 2:

Зверніть увагу: операторів => і =< не існує. Є лише <= і >=. Якщо ви напишете a =< 3, код просто не скомпілюється.

Важливий момент 3:

У Kotlin ви не можете записати вираз виду 18 < age < 65. Адже вираз 18 < age матиме значення true або false. А порівнювати true < 65 (різні типи) не можна. Принаймні в мові Kotlin.

3. Логічні операції

У Kotlin не можна записати вираз 18 < age < 65 — він буде синтаксично некоректним, і застосунок не скомпілюється.

Зате можна записати його так:

(18 < age) І (age < 65)

Звісно, замість слова І там буде інший логічний оператор. Саме про них ми зараз і поговоримо докладніше.

У Kotlin є три логічні оператори: AND (і), OR (або) і NOT (не).

Хороша новина: використовуючи дужки, можна побудувати логічні вирази будь-якої складності.

Погана новина: розробники Kotlin вирішили замість слів and, or і not використовувати позначення з мови C++.

Погляньте на екран:

Логічний оператор Очікування Реальність
І (∧)
and
&&
АБО (∨)
or
||
НЕ (¬)
not
!

Ось кілька прикладів використання логічних операторів у Kotlin:

Вираз Розшифрування Пояснення
(0 < a) && (a < 100)
(0 < a) and (a < 100) (0 < a) І (a < 100)
(!a) && (!b)
(not a) and (not b) (НЕ a) І (НЕ b)
!(!a || !b)
not((not a) or (not b)) НЕ((НЕ a) АБО (НЕ b))

4. Таблиці істинності

Коротко пройдемося логічними операторами.

Оператор AND

Оператор AND, він же І, він же &&, він же конʼюнкція, він же логічне множення.

Вираз Результат
true && true
true
true && false
false
false && true
false
false && false
false

Інакше кажучи, результат виразу дорівнює true (істина) лише тоді, коли обидва значення, що беруть участь у виразі, дорівнюють true (істина). В інших випадках завжди false (хиба).

Оператор OR

Оператор OR, він же АБО, він же ||, він же дизʼюнкція, він же логічне додавання.

Вираз Результат
true || true
true
true || false
true
false || true
true
false || false
false

Інакше кажучи, результат виразу дорівнює true (істина), якщо хоча б одне значення, що бере участь у виразі, дорівнює true (істина). Якщо обидва дорівнюють false, то результат — false.

Оператор NOT

Оператор NOT, він же НЕ, він же !, він же інверсія.

Вираз Результат
!true
false
!false
true

Змінює true на false і навпаки.

Корисні вирази:

Вираз Результат
m && !m
false
m || !m
true
!(a && b)
!a || !b
!(a || b)
!a && !b

5. Приклади логічних операцій: and, or, not

Операція «І», AND, позначається &&

Результат — істина лише тоді, коли обидві змінні істинні.

val age = 16
val hasTicket = true
val canAttend = age >= 14 && hasTicket // true (16 більше 14 І квиток є)

Якщо вам є 14 І у вас є квиток — проходьте!

Операція «АБО», OR, позначається (||)

Результат — істина, якщо хоча б одна умова істинна.

val isAdmin = false
val isModerator = true
val canEdit = isAdmin || isModerator // true (можна редагувати, якщо хоч щось із цього true)

Якщо ви адмін АБО модератор — будь ласка, натискайте кнопки!

Операція «НЕ», NOT, позначається (!)

Оператор інверсії перетворює істину на хибу й навпаки.

val isWeekend = false
val shouldGoToWork = !isWeekend // true (якщо не вихідні, працюємо)

Якщо НЕ вихідні — час вставати!

Комбінування: будуйте умови будь-якої складності

Можна комбінувати скільки завгодно логічних операцій (тільки не перестарайтеся, щоб не вийшло щось на кшталт «якщо він не НЕ не НЕ не адмін…»). Дужки можна (і треба!) використовувати для ясності.

Приклад:

val age = 17
val hasTicket = false
val isVip = true

val canGo = (age >= 18 && hasTicket) || isVip // true, тому що isVip = true

У цьому прикладі логіка така: якщо людина повнолітня і з квитком або якщо вона VIP — пропускаємо. Якщо не VIP, тоді пропускаємо лише тоді, коли вона доросла і з квитком.

6. Коротке замикання

Зараз буде одна з найпрактичніших ідей цього рівня. Логічні оператори && і || у Kotlin працюють так, що іноді друга частина умови взагалі не обчислюється. Це називається коротким замиканням (short-circuit).

Звучить як «проблема електрика», але насправді це надзвичайно корисний механізм. Він допомагає писати умови безпечно. Спершу ми перевіряємо, «чи можна взагалі робити наступну перевірку», і лише потім виконуємо потенційно небезпечні обчислення (наприклад, ділення). У результаті ми уникаємо помилок на кшталт «ділення на нуль» — не тому, що перехоплюємо помилку (винятки будуть пізніше), а тому що не допускаємо її.

Як це працює

Для A && B:

  • якщо A уже false, увесь результат точно false;
  • отже B можна взагалі не обчислювати.

Для A || B:

  • якщо A уже true, увесь результат точно true;
  • отже B теж можна не обчислювати.

Міні‑схема обчислення && і ||

flowchart TD
    A[Обчислити ліву частину A] --> B{Який оператор?}

    B -->|"&&"| C{"A == true?"}
    C -->|"ні"| D[Результат false, B не обчислюємо]
    C -->|"так"| E[Обчислити праву частину B, результат = B]

    B -->|"||" | F{"A == true?"}
    F -->|"так"| G[Результат true, B не обчислюємо]
    F -->|"ні"| H[Обчислити праву частину B, результат = B]

Коротке замикання на практиці: захищаємося від ділення на нуль

Найкласичніший приклад, який справді рятує нерви новачкам: спочатку перевірити, що дільник не нуль, і лише потім ділити.

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

fun main() {
    val x = 0

    if (x != 0 && (10 / x) > 1) {
        println("Частка більша за 1")
    } else {
        println("Або x = 0, або частка не більша за 1") // Пояснення: x = 0 або частка не більша за 1
    }
}

Тут відбувається важлива магія без магії: коли x == 0, вираз x != 0 дає false, і Kotlin не обчислює (10 / x) > 1. Тобто ділення на нуль узагалі не відбувається.

Неправильний порядок: небезпечна частина стоїть першою

Якщо ви напишете навпаки — спочатку ділення, а потім перевірку x != 0, — коротке замикання вже не допоможе, бо до нього треба «дожити». Права частина не врятує, якщо ви «впали» на лівій.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ