User Professor Hans Noodles
Professor Hans Noodles
41 уровень

Тернарный оператор

Статья из группы Java Developer
Привет! Сегодняшняя лекция будет не очень большой, но совершенно точно полезной :) Мы поговорим о так называемом тернарном операторе. Тернарный оператор  - 1“Тернарный” в переводе означает “тройной”. Это альтернатива условному оператору if-else, который тебе уже знаком. Приведем пример. Допустим, какой-то человек решил пойти в кино на фильм с рейтингом 18+. Охранник проверяет его возраст на входе: если он проходит по возрасту — позволяет пройти в зал, если нет — отправляет домой. Создадим класс Man и проверим это с помощью if-else:

public class Man {

   private int age;

   public Man(int age) {
       this.age = age;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       this.age = age;
   }

   public static void main(String[] args) {

       Man man = new Man(22);

       String securityAnswer;

       if (man.getAge() >= 18) {
           securityAnswer = "Все в порядке, проходите!";
       } else {
           securityAnswer = "Этот фильм не подходит для вашего возраста!";
       }

       System.out.println(securityAnswer);

   }
}
Вывод в консоль:

"Все в порядке, проходите!"
Если убрать вывод в консоль, наша проверка выглядит следующим образом:

if (man.getAge() >= 18) {
           securityAnswer = "Все в порядке, проходите!";
       } else {
           securityAnswer = "Этот фильм не подходит для вашего возраста!";
       }
Здесь, по сути, работает простая логика: проверяется одно условие (возраст >= 18). В зависимости от этого в переменную securityAnswer присваивается одна из двух строк с ответом охранника. Такие ситуации, “одно условие — два возможных результата”, встречаются в программировании очень часто. Поэтому для них создали тот самый тернарный оператор. С его помощью мы можем упростить нашу проверку до одной строки кода:

public static void main(String[] args) {

   Man man = new Man(22);

   String securityAnswer = (man.getAge() >= 18) ? "Все в порядке, проходите!" : "Этот фильм не подходит для вашего возраста!";

   System.out.println(securityAnswer);

}
Так и выглядит работа этого оператора. Тернарным (тройным) его называют потому, что в его работе принимают участие 3 компонента:
  • Одно условие (man.getAge() >= 18)
  • Два возможных результата ("Все в порядке, проходите!" и "Этот фильм не подходит для вашего возраста!")
Вначале в коде записывается условие, после которого ставится вопросительный знак.

man.getAge() >= 18 ?
“Возраст человека больше или равно 18?” Далее следует первый результат. Он срабатывает в случае, если условие возвращает true, то есть является истинным:

String securityAnswer = man.getAge() >= 18 ? "Все в порядке, проходите!"
Возраст человека больше или равно 18? Если да — присвоить переменной securityAnswer значение "Все в порядке, проходите!". Далее следует оператор “:” , после которого записывается второй результат. Он срабатывает в случае, если условие возвращает false, то есть является ложным:

String securityAnswer = man.getAge() >= 18 ? "Все в порядке, проходите!" : "Этот фильм не подходит для вашего возраста!";
Возраст человека больше или равно 18? Если да — присвоить переменной securityAnswer значение "Все в порядке, проходите!". Если нет — присвоить переменной securityAnswer значение "Этот фильм не подходит для вашего возраста!" Вот так и выглядит общая логика тернарного оператора. условие ? результат 1 : результат 2 Тернарный оператор  - 2Кстати, скобки вокруг условия ставить не обязательно: мы сделали это для большей читаемости. Сработает и без них:

public static void main(String[] args) {

   Man man = new Man(22);

   String securityAnswer = man.getAge() >= 18 ? "Все в порядке, проходите!" : "Этот фильм не подходит для вашего возраста!";

   System.out.println(securityAnswer);

}
Что же все-таки использовать: if-else, или тернарный оператор? С точки зрения производительности особой разницы нет. Точнее, может она и есть, но незначительная. Здесь вопрос относится скорее к читаемости твоего кода. Он крайне важен в программировании: код, который ты пишешь, должен не только корректно работать, но и легко читаться. Ведь он может перейти “по наследству” к другим программистам, твоим коллегам! И если он будет тяжелым для понимания, это усложнит и их работу, и твою — именно к тебе они будут бегать за объяснениями каждые 5 минут. Общая рекомендация может звучать так: если условие простое и легко проверяется, можно без ущерба использовать тернарный оператор. Таким образом ты сократишь объем кода и количество проверок if-else, которых там и без того может быть немало. А вот если условие является сложным и многоступенчатым — лучше использовать if-else. Например, в этом случае использовать тернарный оператор будет плохой идеей:

String securityAnswer = (man.getAge() >= 18 && (man.hasTicket() || man.hasCoupon()) && !man.hasChild())  ? "Проходите!" : "Вы не можете пройти!";
Так сходу и не поймешь, что тут происходит! Код стал очень сложным для чтения. А все из-за сложного условия:
  • Если человеку больше или равно 18 лет + у него есть билет (или у него есть купон на бесплатное посещение) + с ним нет маленьких детей - тогда он может пройти.
  • Если хотя бы одна из частей условия возвращает false — тогда не может.
Вот здесь явно лучше бы подошло использование if-else. Да, наш код стал бы побольше в размерах, но он был бы в разы более читаемым. И никто из коллег не схватится за голову, если такой код достанется ему в наследство :) Тернарный оператор  - 3Напоследок могу порекомендовать тебе книгу. Мы затронули в лекции тему читаемости кода. Ей посвящена ставшая классикой книга “Чистый код” Роберта Мартина. Тернарный оператор  - 3В ней собраны лучшие практики и рекомендации для программистов, которые позволят тебе писать не только работающий, но и легко читаемый код. Обзор этой книги есть на JavaRush.
Комментарии (104)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Shekerbek Уровень 51, Бишкек, Kyrgyzstan
6 марта 2022
Спасибо
Stas S Уровень 41, Гродно, Беларусь
21 января 2022
А еще можно все условие с тернарным оператором сразу передать нашему "println" в качестве аргумента(параметра) System.out.println(man.getAge() >= 18 ? "Все в порядке, проходите!" : "Этот фильм не подходит для вашего возраста!"); По опыту общения с будущими коллегами программистами (ну я надеюсь) тернарный никто не любит.
Golden Skull Уровень 6, Белгород
23 декабря 2021
public class Man { private int age; public Man(int age) { this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public static void main(String[] args) { Man man = new Man(22); String securityAnswer; if (man.getAge() >= 18) { securityAnswer = "Все в порядке, проходите!"; } else { securityAnswer = "Этот фильм не подходит для вашего возраста!"; } System.out.println(securityAnswer); } } не могу понять, почему IDEA говорит, что нужно проинициализировать String securityAnswer?
maxvell shemet Уровень 2, Казань, Russian Federation
2 декабря 2021
здравствуйте, а если у меня например этих мужчин двое. (один помладше, второй по старше) правила для них общие, но второй проверочный String (для второго мужчины) делать я не собираюсь. желая использовать один result на обоих, имея индивидуальный age. что делать?
Nikvodv Уровень 25, Bryansk, Russian Federation
17 ноября 2021
🤠
Aleksei Reinsalu Уровень 19, Таллинн, Эстония
7 ноября 2021
Если нам нужен метод по логике boolean, но возвращающий не true и false, а сразу какие -то нужные нам в случае true и false штуки. Это могут быть не только строки но и математические вычисления.
Игорь Уровень 33, Москва , Россия
21 июня 2021
3 уровень, прочитал первый пример, вообще не понятно. Создали 3 метода или как, к которым обращаетесь? Правила как их создавать не давали, какие то конструкции не понятные, везде мены в скобках ... Пожалуйста создавайте уроки, чтобы обьяснить одну вещь на понятном языке, а не примерами из недалекого будущего. Минус этой статье. После проятения статьи о легком сравнение у меея осталось куча вопросов что это вообще было?
Виктор Вик Уровень 33, Днепр
15 апреля 2021
Вопрос. Общие уроки по классам прошел, но эти конструкции из примера мне не знакомы. Что они делают, как называются?

   public Man(int age) {
       this.age = age;
   }

   public void setAge(int age) {
       this.age = age;
   }
Чем их действия отличаются? Типа кусок с Man выполняет функцию конструктора объекта типа Man (или класса типа Man - кстати, как правильно?) ? А метод setAge тогда в каких случаях нужен?
Juli Уровень 7, Киев, Украина
3 марта 2021
Подскажите пожалуйста, кто знает. Можно ли в web версии сайта добавить статью или задачу в закладки. В приложении есть кнопка, а тут не могу найти.
Anonymous #2288933 Уровень 8
3 февраля 2021
Возник вопрос по конструктору и сеттеру из первого кода: для чего нужен сеттер в данном случае? Ведь в конструкторе Man уже устанавливается значение для age... Или это оставили на будущее на случай изменений?

public class Man {

   private int age;

   public Man(int age) {
       this.age = age;
   }

   public void setAge(int age) {
       this.age = age;
   }