Мы уже умеем писать методы, которые проверяют одиночные условия. В этом уроке мы продолжим работу с методами и научимся строить составные условия.
Такие навыки пригождаются в довольно распространенных задачах — например, при проверке пароля. Как вы знаете, некоторые сайты при регистрации просят придумать пароль от 8 до 20 символов в длину.
В математике мы бы написали 8 <= x <= 20
, но в Java такой трюк не пройдет. Нам придется сделать два отдельных логических выражения и соединить их специальным оператором «И».
Напишем метод, который принимает пароль и говорит, соответствует ли он условиям:
// Пароль длиннее 8 символов **И** пароль короче 20 символов
public static boolean isCorrectPassword(String password) {
var length = password.length();
return length > 8 && length < 20;
}
isCorrectPassword("qwerty"); // false
isCorrectPassword("qwerty1234"); // true
Оператор &&
означает «И». В этом случае выражение считается истинным, только если истинен каждый операнд — каждое из составных выражений. Другими словами, &&
означает «и то, и другое».
Приоритет этого оператора ниже, чем приоритет операторов сравнения, поэтому выражение отрабатывает правильно без скобок.
Кроме &&
часто используется оператор ||
— «ИЛИ». Он означает «или то, или другое, или оба». Операторы можно комбинировать в любом количестве и любой последовательности. Единственное исключение — когда одновременно встречаются &&
и ||
, то приоритет лучше задавать скобками:
a && b || c; // Без скобок сложно понять приоритет
a && (b || c) // Приоритет очевиден
Рассмотрим еще один пример. Представим, что мы хотим купить квартиру, которая удовлетворяет таким условиям:
Больше 100 м^2 на любой улице ИЛИ больше 80 м^2 на центральной улице Main Street
Напишем метод, проверяющий квартиру. Он принимает два параметра: площадь и название улицы:
isGoodApartment(91, "Queens Street"); // false
isGoodApartment(78, "Queens Street"); // false
isGoodApartment(70, "Main Street"); // false
isGoodApartment(120, "Queens Street"); // true
isGoodApartment(120, "Main Street"); // true
isGoodApartment(80, "Main Street"); // true
public static boolean isGoodApartment(int area, String street) {
return area >= 100 || (area >= 80 && "Main Street".equals(street));
}
https://replit.com/@hexlet/java-basics-logical-operators
Область математики, в которой изучаются логические операторы, называется булевой алгеброй. Ниже показаны «таблицы истинности» — по ним можно определить, каким будет результат применения оператора:
&&
| 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
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Ваше упражнение проверяется по этим тестам
1import static org.assertj.core.api.Assertions.assertThat;
2
3class Test {
4 public static void main(String[] args) {
5 assertThat(App.isLeapYear(2016)).isTrue();
6 assertThat(App.isLeapYear(2000)).isTrue();
7 assertThat(App.isLeapYear(2017)).isFalse();
8 assertThat(App.isLeapYear(2018)).isFalse();
9 assertThat(App.isLeapYear(1900)).isFalse();
10 }
11}
12
Решение учителя откроется через: