Как называется оператор Java ?: и что он делает?

Я работаю с Java пару лет, но до недавнего времени я не сталкивался с этой конструкцией:

int count = isHere ? getHereCount(index) : getAwayCount(index);

Это, наверное, очень простой вопрос, но может ли кто-нибудь объяснить его? Как мне это прочитать? Я почти уверен, что знаю, как это работает.

  • если isHere истинно, вызывается getHereCount(),
  • если isHere ложно, вызывается getAwayCount().

Правильный? Как называется эта конструкция?


person mainstringargs    schedule 28.04.2009    source источник
comment
См. также stackoverflow.com/questions/795286/what-does-do-in-c для версии этого вопроса на С++ (фактически заданной только вчера).   -  person Michael Myers    schedule 28.04.2009
comment
Имейте в виду, что мир C/C++/Java довольно поровну разделен между людьми, считающими его уродливым и запутанным и избегающим его, как чумы, и людьми, которые думают, что вы не можете утверждать, что знаете C, C++ или Java, если вы не могу распознать его и использовать, не задумываясь.   -  person Paul Tomblin    schedule 28.04.2009
comment
Обычно в Java считается дурным тоном использовать его за пределами самых ясных и простых случаев. Если вы обнаружите, что вкладываете их, вам конец. С другой стороны, в культуре C, где быстрый и умный код ценится выше ясности, он считается приемлемым.   -  person Yishai    schedule 28.04.2009
comment
ответ_на_вопрос = (распознавание_оператора) ? (социальное_принятие) : (снисходительно_пальцевый_ваг)   -  person Dan    schedule 28.04.2009
comment
Вы можете обратиться к этому ресурсу для получения дополнительной информации.   -  person Shiva    schedule 05.02.2018


Ответы (16)


Да, это сокращенная форма

int count;
if (isHere)
    count = getHereCount(index);
else
    count = getAwayCount(index);

Он называется условным оператором. Многие люди (ошибочно) называют его тернарным оператором, потому что это единственный тернарный (с тремя аргументами) оператор в Java, C, C++ и, вероятно, во многих других языках. Но теоретически может существовать еще один тернарный оператор, тогда как условный оператор может быть только один.

Официальное название дается на языке Java. Спецификация:

§15.25 Условный оператор? :

Условный оператор ? : использует логическое значение одного выражения, чтобы решить, какое из двух других выражений следует оценить.

Обратите внимание, что обе ветви должны вести к методам с возвращаемыми значениями:

Если второе или третье операндное выражение является вызовом метода void, возникает ошибка времени компиляции.

На самом деле, по грамматике выражений (§14.8), не допускается появление условного выражения в любом контексте, в котором может появиться вызов метода void.

Итак, если doSomething() и doSomethingElse() являются пустыми методами, вы не можете сжать это:

if (someBool)
    doSomething();
else
    doSomethingElse();

в это:

someBool ? doSomething() : doSomethingElse();

Простые слова:

booleanCondition ? executeThisPartIfBooleanConditionIsTrue : executeThisPartIfBooleanConditionIsFalse 
person Michael Myers    schedule 28.04.2009
comment
Я не понимаю, что нижний делает неправильно. Я верю тебе и всем. Просто мне он кажется таким же, как и оригинал. Это потому, что они просто вызывают другую функцию, которая может возвращать или не возвращать значение и разрешать выполнение следующего набора кода? - person johnny; 01.05.2009
comment
Я предполагаю, что doSomething() и doSomethingElse() являются недействительными методами. Последний бит спецификации говорит о том, что тернарный оператор должен возвращать значение, поэтому ни один из операндов не может быть пустым методом. - person Michael Myers; 01.05.2009
comment
Это говорит немного больше, чем это. В нем говорится, что условный оператор не разрешен там, где МОЖЕТ появиться метод void. Так, например, следующие операторы: VALID: String x = (false) ? Х : У; НЕДЕЙСТВИТЕЛЬНО: (ложь) ? Х : У; - person kenj0418; 07.11.2013
comment
Не будет ошибкой назвать его тернарным оператором, как не будет ошибкой (в 2016 г.) назвать Обаму президентом, хотя возможно, что в будущем будут и другие президенты. - person Dawood ibn Kareem; 08.10.2016
comment
@DawoodibnKareem - полностью согласен, и тот же JLS, который мы здесь обсуждаем, говорит следующее The ternary conditional operator ? : (§15.25) тоже. - person Isank; 04.11.2017
comment
@DawoodibnKareem Я думаю, что Майкл намеренно включил the в курсив the ternary operator, и это то, что он имеет в виду, ошибочно, а не то, что ternary operator ошибочно. Тернарный оператор подразумевает, что, как говорит Майкл, он единственный, что, в свою очередь, может привести к предположению, что не может быть никаких других тернарных операторов, что, по словам Майкла, ошибочно, и я согласен, это было бы ошибочным предположением. - person Ghoti and Chips; 23.11.2017
comment
Обратите внимание, что документация на самом деле называет его условным оператором; тернарный docs.oracle.com/javase/tutorial/java/nutsandbolts/< /а> - person Mark Schultheiss; 20.05.2018

Другие ответили на это в разумной степени, но часто с именем «тройной оператор».

Будучи педантом, я хотел бы уточнить, что имя оператора - условный оператор или «условный оператор ?:». Это тернарный оператор (в том смысле, что он имеет три операнда), и на данный момент это единственный тернарный оператор в Java.

Однако спецификация довольно ясна что его имя является условным оператором или "условным оператором ?:", чтобы быть абсолютно однозначным. Я думаю, что понятнее называть его этим именем, поскольку оно в некоторой степени указывает на поведение оператора (оценка условия), а не только на количество операндов, которые у него есть.

person Jon Skeet    schedule 28.04.2009
comment
Этот ответ технически правильный. Однако, поскольку существует только один тернарный оператор, его часто называют тернарным оператором. Несмотря на то, что это имя не передает полного значения оператора, оно прижилось. Если вы упомянули тернарный оператор, программисты поймут, о чем вы говорите. Спецификация, которую вы упомянули, также относится к этому оператору как к троичному условному оператору, который кажется более информативным. java.sun.com/docs/books/jls/ третье_издание/html/ - person Gary; 28.04.2009
comment
Я просто думаю, что стоит называть что-то своим определенным именем. В частности, если в Java когда-нибудь появится еще один тернарный оператор, люди, которые используют термин условный оператор, все равно будут правы и недвусмысленны, в отличие от тех, кто просто говорит тернарный оператор. Да, фраза «тернарный оператор» прижилась — мой ответ является частью попытки ее отклеить, точно так же, как я пытаюсь исправить утверждение о том, что объекты передаются по ссылке. - person Jon Skeet; 28.04.2009
comment
Могу я направить вас на эту страницу Oracle, где говорится о три условных оператора, но только один тернарный оператор? Если вы хотите, чтобы было ясно, какой оператор вы имеете в виду, вероятно, лучше использовать имя, которое использует большинство людей. (Да, я знаю, что появлюсь на вечеринке как раз в тот момент, когда хозяин моет последнюю посуду). - person Dawood ibn Kareem; 08.10.2016
comment
@DavidWallace: Лучше использовать условный оператор ?:, ИМО - отредактирую, чтобы уточнить это. Но я думаю, что стоит убедить людей использовать настоящее имя оператора, а не сосредотачиваться на одном его аспекте (сколько у него операндов), который не имеет ничего общего с его поведением. (Кроме того, руководства нередко бывают менее точными, чем спецификация, которая вызывает && оператор условного-и и ||оператор условного-или, но использует только условный оператор для ?:. - person Jon Skeet; 08.10.2016
comment
Я не знаю. Если кто-то скажет мне условный оператор, я не буду уверен, что они имеют в виду. Там, откуда я родом (противоположный конец света от вас), люди просто не называют это так. Если говорят тернарный оператор или хук-оператор, то я понимаю. Я восхищаюсь вашими амбициями, желанием изменить то, как люди говорят. Если кто и может это сделать, так это ты. Но я не питаю особой надежды и не вижу особого смысла. - person Dawood ibn Kareem; 08.10.2016
comment
@DavidWallace: Я бы сказал, что если кто-то говорит вам условный оператор, вам должно быть понятно, что он имеет в виду, и если он на самом деле означает && или ||, он должен был сказать условный-и или условный-или, если только это абсолютно ясно из контекста. Если бы кто-то сказал мне оператор хука, я бы понятия не имел, что они имели в виду. И да, такое постепенное улучшение сообщества возможно возможно — 20 лет назад люди очень часто говорили о том, что Java передается по ссылке; в наши дни это все еще всплывает, но исправляется очень быстро. - person Jon Skeet; 08.10.2016
comment
Да, я должен. Я, вероятно, нет. И это может стать сложнее, если в Java появятся новые условные операторы, которые обсуждались для работы с нулевыми значениями. - person Dawood ibn Kareem; 08.10.2016
comment
@DavidWallace: я ожидаю, что они получат новые имена, точно так же, как в C# есть условный нулевой оператор, но условный оператор по-прежнему является именем для ?:. - person Jon Skeet; 08.10.2016
comment
Будет интересно посмотреть, что произойдет, если Java когда-нибудь получит что-то вроде операторов ?? и ?. в C#. В то же время я должен сказать, что я использую ?: так редко, что единственный раз, когда я могу говорить об этом, — когда отвечаю или комментирую вопросы Stack Overflow. С этого момента я постараюсь не забывать называть это условным оператором в своих ответах. Спасибо за вашу мудрость и руководство. - person Dawood ibn Kareem; 08.10.2016

Согласно спецификации Sun Java, это называется Условный оператор. См. раздел 15.25. Вы правы относительно того, что он делает.

Условный оператор? : использует логическое значение одного выражения, чтобы решить, какое из двух других выражений следует оценить.

Условный оператор синтаксически правоассоциативен (группирует справа налево), так что a?b:c?d:e?f:g означает то же, что и a?b:(c?d:(e?f :грамм)).

ConditionalExpression:
        ConditionalOrExpression
        ConditionalOrExpression ? Expression : ConditionalExpression

У условного оператора есть три операндных выражения; ? появляется между первым и вторым выражениями, а : появляется между вторым и третьим выражениями.

Первое выражение должно иметь тип boolean или Boolean, иначе произойдет ошибка времени компиляции.

person JRL    schedule 28.04.2009

int count = isHere ? getHereCount(index) : getAwayCount(index);

означает :

if (isHere) {
    count = getHereCount(index);
} else {
    count = getAwayCount(index);
}
person Romain Linsolas    schedule 28.04.2009

Не совсем правильно, если быть точным:

  1. если isHere равно true, результат getHereCount() возвращается
  2. в противном случае результат getAwayCount() возвращается

То, что «вернулось», очень важно. Это означает, что методы должны возвращать значение, и это значение должно где-то быть присвоено.

Кроме того, он не совсем синтаксически эквивалентен варианту if-else. Например:

String str1,str2,str3,str4;
boolean check;
//...
return str1 + (check ? str2 : str3) + str4;

При кодировании с помощью if-else всегда будет больше байт-кода.

person RichN    schedule 28.04.2009
comment
Я считаю, что javac может генерировать один и тот же байт-код. Хотя вы правы, что есть неясные угловые случаи, когда они не эквивалентны. - person Tom Hawtin - tackline; 29.04.2009
comment
Ну конечно; естественно. Для меня истинным достоинством условного оператора является приведенный мной пример. Альтернативой являются: // вздох!! Строка темп = ул1; если (проверить) temp += str2; иначе темп += ул3; темп += стр4; температура возврата; или ручное кодирование операции добавления StringBuilder. 1-й страдает серьезной проблемой эффективности, а 2-й слишком многословен и требует кропотливых усилий без особого результата. - person RichN; 29.04.2009

Тернарный, условный; помидор, помидор. Что действительно ценно, так это инициализация переменных. Если (как и я) вы любите инициализировать переменные там, где они определены, условный тернарный оператор (поскольку это и то, и другое) позволяет вам делать это в тех случаях, когда есть условия относительно его значения. Особенно заметно в конечных полях, но полезно и в других местах.

e.g.:

public class Foo {
    final double    value;

    public Foo(boolean positive, double value) {
        this.value = positive ? value : -value;
    }
}

Без этого оператора — под любым именем — вам пришлось бы сделать поле неконечным или написать функцию просто для его инициализации. На самом деле это неправильно — его все равно можно инициализировать с помощью if/else, по крайней мере на Яве. Но я нахожу это чище.

person Carl Manaster    schedule 28.04.2009

condition ? truth : false;

Если условие равно true, оцените первое выражение. Если условие false, оцените второе выражение.

Он называется условным оператором и представляет собой тип Тернарная операция.

person Joe Phillips    schedule 28.04.2009
comment
Согласно JLS, 15.25. Условный оператор? : это оценка, а не возврат и выражение, а не параметр. - person Gerold Broser; 09.06.2020

Эта конструкция называется Тернарный оператор в области информатики и программирования.
И Википедия предлагает следующее объяснение:

В информатике тернарный оператор (иногда его неправильно называют третичным оператором) — это оператор, который принимает три аргумента. Аргументы и результат могут быть разных типов. Многие языки программирования, использующие синтаксис, подобный C, имеют тернарный оператор ?: , который определяет условное выражение.

Этот синтаксис доступен не только в Java, но и в PHP, и в Objective-C.

В следующей ссылке приводится следующее объяснение, которое полезно понять Это:

Тернарный оператор — это некоторая операция, работающая с 3 входами. Это сокращение для оператора if-else, также известное как условный оператор.

В Perl/PHP это работает так:
boolean_condition ? true_value : false_value

В C/C++ это работает так:
logical expression ? action for true : action for false

Это может быть удобочитаемым для некоторых логических условий, которые не слишком сложны, в противном случае лучше использовать блок If-Else с предполагаемой комбинацией условной логики.

Мы можем упростить блоки If-Else с помощью этого тернарного оператора для одной строки оператора кода.
Например:

if ( car.isStarted() ) {
     car.goForward();
} else {
     car.startTheEngine();
}

Может быть равно следующему:

( car.isStarted() ) ? car.goForward() : car.startTheEngine();

Итак, если мы обратимся к вашему утверждению:

int count = isHere ? getHereCount(index) : getAwayCount(index);

На самом деле это 100% эквивалент следующего блока If-Else:

int count;
if (isHere) {
    count = getHereCount(index);
} else {
    count = getAwayCount(index);
}

Вот и все!
Надеюсь, это было кому-то полезно!
Ура!

person Randika Vishman    schedule 13.09.2015

Правильный. Он называется тернарным оператором. Некоторые также называют его условным оператором.

person cletus    schedule 28.04.2009
comment
Цитируя Алису в стране чудес, это называется тернарным оператором, но его имя — условный оператор. - person Paul Tomblin; 28.04.2009
comment
Но имя его называется оператором двоеточия с вопросительным знаком. - person Michael Myers; 28.04.2009
comment
Именование именования звучит немного C++ish. Оператор двоеточия вопросительного знака ?: (один токен) известен как оператор Элвиса. - person Tom Hawtin - tackline; 29.04.2009

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

String s = mayBeNull?.toString() ?: "null";

Было бы особенно удобно там, где происходит автораспаковка.

Integer ival = ...;  // may be null
int i = ival ?: -1;  // no NPE from unboxing

Он был выбран для дальнейшего рассмотрения в рамках JDK 7 "Project Coin".

person erickson    schedule 28.04.2009
comment
Этот оператор не является одним из моих любимых в Project Coin. Ограниченная полезность, не интуитивно понятный для чтения и просто уродливый, как и все остальные. Хотя, может быть, он у меня вырос бы. - person Michael Myers; 28.04.2009
comment
IIRC‹ Нил этого не предлагал. Он просто использовал его как простой пример того, как написать предложение. Подробнее в архиве списка рассылки монет проекта. - person Tom Hawtin - tackline; 29.04.2009

Тернарный оператор(?:)

The ternary operator is an operator that takes three arguments. The first 
argument is a comparison argument, the second is the result upon a true 
comparison, and the third is the result upon a false comparison.
person Darsy    schedule 25.04.2017

На самом деле это может занять более 3 аргументов. Например, если мы хотим проверить, является ли число положительным, отрицательным или нулем, мы можем сделать это:

String m= num > 0 ? "is a POSITIVE NUMBER.": num < 0 ?"is a NEGATIVE NUMBER." :"IT's ZERO.";

что лучше, чем использование if, else if, else.

person Praised    schedule 02.09.2018

Это условный оператор, и это больше, чем просто краткий способ написания операторов if.

Поскольку это выражение, которое возвращает значение, его можно использовать как часть других выражений.

person justinhj    schedule 28.04.2009

Да вы правы. ?: обычно называют «тернарным условным оператором», часто называемым просто «тройным оператором». Это сокращенная версия стандартного оператора if/else.

Тернарный условный оператор

person Gary    schedule 28.04.2009

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

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

Во-первых, это дело Оригинального Аскера. Он просто потратил час, публикуя об этом и читая ответы. Сколько времени потребовалось бы автору, чтобы написать каждый ?: как если/то на протяжении всей своей жизни. Не час, чтобы быть уверенным.

Во-вторых, в C-подобных языках вы привыкаете просто знать, что условные операторы стоят на первом месте. Я заметил это, когда использовал Ruby и наткнулся на такие строки:

callMethodWhatever(Long + Expression + with + syntax) if conditional

Если бы я долгое время был пользователем Ruby, у меня, вероятно, не было бы проблем с этой строкой, но, начиная с C, когда вы видите "callMethodWhatever" в качестве первого элемента в строке, вы ожидаете, что она будет выполнена. Знак ?: менее загадочен, но все же достаточно необычен, чтобы сбить читателя с толку.

Преимущество, однако, заключается в том, что у вас в животе действительно классное ощущение, когда вы можете написать 3-строчный оператор if на месте 1 из строк. Не могу этого отрицать :) Но, честно говоря, не обязательно более читабельным для 90% людей просто из-за его редкости.

Когда это действительно присваивание, основанное на логическом значении и значениях, у меня нет проблем с этим, но им легко злоупотреблять.

person Bill K    schedule 28.04.2009

Условные выражения имеют совершенно другой стиль, без явного выражения if в операторе.

Синтаксис: логическое выражение? выражение1 : выражение2;

Результатом этого условного выражения является

выражение1, если логическое-выражение истинно;

в противном случае результатом будет выражение2.

Предположим, вы хотите присвоить максимальное количество переменных num1 и num2. Вы можете просто написать оператор, используя условное выражение: max = (num1 > num2) ? число1 : число2;

Примечание. Символы ? и : появляются вместе в условном выражении. Они образуют условный оператор и также называются тернарными операторами, потому что они используют три операнда. Это единственный тернарный оператор в Java.

цитируется из: Введение в программирование на Java, 10-е издание, Ю. Даниэль Лян, стр. 126–127.

person Ged    schedule 24.06.2019