Василий Малик
Senior Java-разработчик в CodeGym

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

Статья из группы 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.
Комментарии (129)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Kaz Уровень 4
30 марта 2023
Кто на 3-ем уровне и не врубает, как я, почему в этих доп.лекциях используют какие-то самодельные man/car, вместо Scanner/String... ставим лайки
AleksandrB. Уровень 4
20 марта 2023
Круто 👍
Anatoly Уровень 4
19 марта 2023
^-^
Ислам Уровень 5
11 марта 2023
очень интересная лекция.
Larvixx Уровень 16
2 февраля 2023
String securityAnswer = (man.getAge() >= 18 && (man.hasTicket() || man.hasCoupon()) && !man.hasChild()) ? "Проходите!" : "Вы не можете пройти!"; Ну это ещё достаточно читаемо )), не думаю что если запихать это в "if else" станет намного легче.
Timur Khasmamedov Уровень 14 Expert
9 января 2023
Если что, можно выводить на экран сразу с тернарником - строка 5 из последнего "правильного" подхода. Но если потом переменная нужна, то придется объявить.
Kergshi Уровень 10
7 января 2023
Это для кого статья? Я получи ссылку на неё на 3-м уровне,но уже в первом примере много чего непонятно. Как я должен понять,что там вообще происходит? Всё,что до 17-й строки,что это такое? Да даже если с 17 смотреть. Вот-вот переход на 4-й уроветь. А что такое в параметрах main " String[] args" Почему ничего из этого не объясняется?
FORES Уровень 24
24 декабря 2022
Подскажите, пожалуйста, возможно ли использовать тернарный оператор внутри цикла while? Если условие выполняется - вывод текста, если нет - завершение цикла. Как выводить один или второй текст, понятно. А как реализовать вывод текста или прерывание цикла не понятно...
Xelin Уровень 34
6 декабря 2022
Спасибо! Помогли разобраться с этой темой
linx Уровень 4
9 ноября 2022
Запутался Перечитал: все комментарии, ссылки с : setter and getter, конструктор. И не нашёл обьяснения на строку: "Man man = new man" , а до этого обьясняли так : "String a = 5;" , где : переменной(a), типа(String), присваивается(=), значение(5), здесь так не сходиться А в другом обьяснении слово "new" выводит из "pull" строку отдельной частью памяти. Какае-то каша о_0