/
Программирование
/
Курс Java
/

Логические операторы

Java: Логические операторы

Мы уже умеем писать методы, которые проверяют одиночные условия. В этом уроке мы продолжим работу с методами и научимся строить составные условия.

Такие навыки пригождаются в распространенных задачах, например при проверке пароля. Некоторые сайты при регистрации просят придумать пароль от 8 до 20 символов в длину.

В математике мы записали бы это как 8 <= x <= 20, но в Java такой трюк не пройдет. Нам придется сделать два отдельных логических выражения и соединить их специальным оператором "И".

Напишем метод, который принимает пароль и говорит, соответствует ли он условиям. Результат выводим на экран:

// Пароль длиннее 8 символов И пароль короче 20 символов
public static boolean isCorrectPassword(String password) {
    var length = password.length();
    return length > 8 && length < 20;
}

System.out.println(App.isCorrectPassword("qwerty"));     // => false
System.out.println(App.isCorrectPassword("qwerty1234")); // => true

Оператор && означает "И". В математической логике это называют конъюнкцией. Все выражение считается истинным, только когда истинен каждый операнд, то есть каждое из составных выражений. Другими словами, && означает "и то, и другое". Приоритет этого оператора ниже, чем приоритет операторов сравнения, поэтому выражение length > 8 && length < 20 отрабатывает правильно без скобок.

Кроме && часто используется оператор ||, который означает "ИЛИ" (дизъюнкция). Он читается как "или то, или другое, или оба". Выражение a || b считается истинным, когда истинен хотя бы один из операндов или когда истинны оба. В остальных случаях выражение ложное.

Посмотрим на метод, который определяет, положена ли человеку скидка. Скидку дают тем, кто младше 18 лет, или студентам:

public static boolean hasDiscount(int age, boolean isStudent) {
    return age < 18 || isStudent;
}

System.out.println(App.hasDiscount(15, false)); // => true  (младше 18)
System.out.println(App.hasDiscount(25, true));  // => true  (студент)
System.out.println(App.hasDiscount(15, true));  // => true  (оба условия)
System.out.println(App.hasDiscount(25, false)); // => false

Операторы можно комбинировать в любом количестве и любой последовательности. Когда в коде одновременно встречаются && и ||, приоритет лучше задавать скобками:

a && b || c;   // Без скобок сложно понять приоритет
a && (b || c); // Со скобками понятно, что к чему относится

Рассмотрим еще один пример. Представим, что мы хотим купить квартиру, которая удовлетворяет таким условиям:

От 100 м² на любой улице ИЛИ от 80 м² на центральной улице Main Street

Напишем метод, проверяющий квартиру. Он принимает два параметра, площадь и название улицы. Строки сравниваем через .equals(...), потому что для строк это правильный способ проверки на равенство:

public static boolean isGoodApartment(int area, String street) {
    return area >= 100 || (area >= 80 && "Main Street".equals(street));
}

System.out.println(App.isGoodApartment(91, "Queens Street")); // => false
System.out.println(App.isGoodApartment(78, "Queens Street")); // => false
System.out.println(App.isGoodApartment(70, "Main Street"));   // => false

System.out.println(App.isGoodApartment(120, "Queens Street")); // => true
System.out.println(App.isGoodApartment(120, "Main Street"));   // => true
System.out.println(App.isGoodApartment(80, "Main Street"));    // => true

Скобки вокруг area >= 80 && "Main Street".equals(street) задают приоритет. Без них правило прочиталось бы иначе, а так сразу видно, какая часть относится к какому оператору.

Таблицы истинности

Область математики, в которой изучаются логические операторы, называется булевой алгеброй. Таблицы истинности показывают, каким будет результат при применении каждого оператора.

Оператор И &&

ABA && B
truetruetrue
truefalsefalse
falsetruefalse
falsefalsefalse

Оператор ИЛИ ||

ABA ❘❘ B
truetruetrue
truefalsetrue
falsetruetrue
falsefalsefalse

Задание

Реализуйте метод isLeapYear(), который определяет является ли год високосным или нет. Год будет високосным, если он кратен (то есть делится без остатка) 400 или он одновременно кратен 4 и не кратен 100. Как видите, в определении уже заложена вся необходимая логика, осталось только переложить её на код:

App.isLeapYear(2018); // false
App.isLeapYear(2017); // false
App.isLeapYear(2016); // true

Кратность можно проверять так:

// % - возвращает остаток от деления левого операнда на правый
// Проверяем что number кратен 10
number % 10 == 0

// Проверяем что number не кратен 10
number % 10 != 0

Полезное

Команда проекта находится в телеграм-сообществе. Там можно задать любой вопрос и повлиять на проект

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются