views:

1751

answers:

14

I have been working with Java a couple of years, but up until recently I haven't run across this construct:

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

This is probably a very simple question, but can someone explain it? How do I read it? I am pretty sure I know how it works.

  • if isHere is true, getHereCount() is called,
  • if isHere is false getAwayCount() is called.

Correct? What is this construct called?

+1  A: 

Correct. It's called the ternary operator. Some also call it the conditional operator.

cletus
To quote Alice In Wonderland, it's called the ternary operator, but its name is the Conditional Operator.
Paul Tomblin
But the name of it is called the question-mark colon operator.
Michael Myers
Naming naming sound a bit C++ish. The question mark colon operator ?: (one token) is known as the Elvis operator.
Tom Hawtin - tackline
+36  A: 

Yes, it's a shorthand form of

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

It's called the conditional operator. Many people (erroneously) call it the ternary operator, because it's the only ternary (three-argument) operator in Java, C, C++, and probably many other languages. But theoretically there could be another ternary operator, whereas there can only be one conditional operator.

Edit: The official name is given in the Java Language Specification:

§15.25 Conditional Operator ? :

The conditional operator ? : uses the boolean value of one expression to decide which of two other expressions should be evaluated.

Also, here is a tidbit from the spec that hasn't been mentioned:

Note that it is a compile-time error for either the second or the third operand expression to be an invocation of a void method. In fact, it is not permitted for a conditional expression to appear in any context where an invocation of a void method could appear (§14.8).

So you cannot compress this:

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

into this:

someBool ? doSomething() : doSomethingElse();
Michael Myers
I don't understand what the bottom one does that is wrong. I believe you and all. It just looks the same to me as the original. Is it because they just call another function that may or may not return a value and allow the next code set to run?
johnny
I'm assuming doSomething() and doSomethingElse() are void methods. What that last bit of the spec says is that the ternary operator *must* return a value, so none of the operands can be void methods.
Michael Myers
+2  A: 
int count = isHere ? getHereCount(index) : getAwayCount(index);

means :

if (isHere) {
    count = getHereCount(index);
} else {
    count = getAwayCount(index);
}
romaintaz
A: 

Yes, you are correct. ?: is typically called the "ternary conditional operator", often referred to as simply "ternary operator". It is a shorthand version of the standard if/else conditional.

Ternary Conditional Operator

Gary
+2  A: 
condition ? truth : false;

If the condition is true then return the first parameter. If the condition is false, return the second parameter.

It is called the Conditional Operator and it is a type of Ternary Operation.

Joe Philllips
+11  A: 

According to the Sun Java Specification, it's called the Conditional Operator. See section 15.25. You're right as to what it does.

The conditional operator ? : uses the boolean value of one expression to decide which of two other expressions should be evaluated.

The conditional operator is syntactically right-associative (it groups right-to-left), so that a?b:c?d:e?f:g means the same as a?b:(c?d:(e?f:g)).

ConditionalExpression:
        ConditionalOrExpression
        ConditionalOrExpression ? Expression : ConditionalExpression

The conditional operator has three operand expressions; ? appears between the first and second expressions, and : appears between the second and third expressions.

The first expression must be of type boolean or Boolean, or a compile-time error occurs.

JRL
Nice to see someone else getting the name right. :)
Jon Skeet
A: 

It's the conditional operator, and it's more than just a concise way of writing if statements.

Since it is an expression that returns a value it can be used as part of other expressions.

justinhj
+16  A: 

Others have answered this to reasonable extent, but often with the name "ternary operator".

Being the pedant that I am, I'd like to make it clear that the name of the operator is the conditional operator. It's a ternary operator (in that it has three operands) and it happens to be the only ternary operator in Java at the moment.

However, the spec is pretty clear that its name is the conditional operator. I think it's clearer to call it by that name, as it indicates the behaviour of the operator to some extent (evaluating a condition) rather than just how many operands it has.

Jon Skeet
This answer is technically correct. However, since there is only one ternary operator you often see it referred to as the ternary operator. Even though this name does not convey the complete meaning of the operator, it is a name that has stuck. If you mention the name "ternary operator", programmers know what you are talking about. The spec you mention also refers to this operator as the "Ternary Conditional" which seems more informative.http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.28
Gary
I just think it's worth calling something by its defined name. In particular, if Java ever gets another ternary operator, people who use the term "conditional operator" will still be correct and unambiguous - unlike those who just say "ternary operator". Yes, the phrase "ternary operator" has stuck - my answer is part of an effort to "unstick" it, just as I try to correct the claim that "objects are passed by reference".
Jon Skeet
+1  A: 

The ternary operator is one of those things C programmers created to make it possible to write powerful, compact code in as few lines as possible (like ++ and -- ). It can get pretty confusing when you have it 3 times on one line... :D

CrazyJugglerDrummer
You know it helps sometimes:log.debug("Number of kittens:" + (array==null? "(null)": array.size()));
KarlP
Oh yes, its very helpful often times. It has its place just like any programming feature, but everything has advantages and disadvantages and a time and place.
CrazyJugglerDrummer
+2  A: 

Not exactly correct, to be precise:

  1. if isHere is true, the result of getHereCount() is returned
  2. otheriwse the result of getAwayCount() is returned

That "returned" is very important. It means the methods must return a value and that value must be assigned somewhere.

Also, it's not exactly syntactically equivalent to the if-else version. For example:

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

If coded with if-else will always result in more bytecode.

RichN
I believe javac is at liberty to generate the same bytecode. Although you are correct that there are obscure corner cases where they are not equivalent.
Tom Hawtin - tackline
Yes, of course.For me, the true merit of the conditional operator is the example I've given. The alternative are either: // gasp!! String temp = str1; if (check) temp += str2; else temp += str3; temp += str4; return temp;or handcoding the StringBuilder append operation. The 1st one suffer from serious efficiency issue while the 2nd one is too verbose and is a painstaking effort without much gain.
RichN
A: 

I happen to really like this operator, but I never use it at work.

You always have to balance code compactness with the time spent reading it, and in that it has some pretty severe flaws.

First of all, there is the posters case. He just spent an hour posting about it and reading the responses. How longer would it have taken the author to write every ?: as an if/then throughout the course of his entire life. Not an hour to be sure.

Secondly, in C-like languages, you get in the habit of simply knowing that conditionals are the first thing in the line. I noticed this when I was using Ruby and came across lines like:

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

If I was a long time Ruby user I probably wouldn't have had a problem with this line, but coming from C, when you see "callMethodWhatever" as the first thing in the line, you expect it to be executed. The ?: is less cryptic, but still unusual enough as to throw a reader off.

The advantage, however, is a really cool feeling in your tummy when you can write a 3-line if statement in the space of 1 of the lines. Can't deny that :) But honestly, not necessarily more readable by 90% of the people out there simply because of its' rarity.

Bill K
+1  A: 

Ternary, conditional; tomato, tomatoh. What it's really valuable for is variable initialization. If (like me) you're fond of initializing variables where they are defined, the conditional ternary operator (for it is both) permits you to do that in cases where there is conditionality about its value. Particularly notable in final fields, but useful elsewhere, too.

e.g.:

public class Foo {
    final double value;

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

Without that operator - by whatever name - you would have to make the field non-final or write a function simply to initialize it. Actually, that's not right - it can still be initialized using if/else, at least in Java. But I find this cleaner.

Carl Manaster
A: 

You might be interested in a proposal for some new operators that are similar to the conditional operator. The null-safe operators will enable code like this:

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

It would be especially convenient where auto-unboxing takes place.

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

It has been selected for further consideration under JDK 7's "Project Coin."

erickson
That operator is not one of my favorites from Project Coin. Limited usefulness, not intuitive to read, and just plain ugly as all get-out. Maybe it would grow on me, though.
Michael Myers
I'm not a huge fan either, actually. It's a Neal Gafter proposal, and he tends to see things very differently from your average Java programmer, who tend to see things differently from your average human being. The only places I might like a little help with nulls is in a foreach loop, testing whether the iterable is null, and auto-unboxing.
erickson
IIRC< Neal didn't propose it. He just used it as a simple example of how to write a proposal. More details on the project coin mailing list archive.
Tom Hawtin - tackline
I just read the intro to the proposal, and you are right. It's Stephen Colebourne of Joda and "there's no Java 7" fame.
erickson