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) задают приоритет. Без них правило прочиталось бы иначе, а так сразу видно, какая часть относится к какому оператору.
Таблицы истинности
Область математики, в которой изучаются логические операторы, называется булевой алгеброй. Таблицы истинности показывают, каким будет результат при применении каждого оператора.
Оператор И &&
| A | B | A && B |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
Оператор ИЛИ ||
| A | B | A ❘❘ B |
|---|---|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
Задание
Реализуйте метод 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Полезное
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) задают приоритет. Без них правило прочиталось бы иначе, а так сразу видно, какая часть относится к какому оператору.
Таблицы истинности
Область математики, в которой изучаются логические операторы, называется булевой алгеброй. Таблицы истинности показывают, каким будет результат при применении каждого оператора.
Оператор И &&
| A | B | A && B |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
Оператор ИЛИ ||
| A | B | A ❘❘ B |
|---|---|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
Задание
Реализуйте метод 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Полезное
Ваше упражнение проверяется по этим тестам
import static org.assertj.core.api.Assertions.assertThat;
class AppTest {
public static void main(String[] args) {
assertThat(App.isLeapYear(2016)).isTrue();
assertThat(App.isLeapYear(2000)).isTrue();
assertThat(App.isLeapYear(2017)).isFalse();
assertThat(App.isLeapYear(2018)).isFalse();
assertThat(App.isLeapYear(1900)).isFalse();
}
}Решение учителя откроется через:
20:00
