Java: Ternary with no return. (For method calling)

JavaMethodsBooleanReturnTernary

Java Problem Overview


I was wondering if it was possible to do a ternary operation but without returning anything.

If it's not possible in Java is it possible in other languages, if so which ones apply?

name.isChecked() ? name.setChecked(true):name.setChecked(false);

Java Solutions


Solution 1 - Java

No, you can't. But what's the point of this over an if-else statement? Are you really trying to save 7 characters?

if (name.isChecked()) {
    name.setChecked(true);
} else {
    name.setChecked(false);
}

or if you prefer bad style:

if (name.isChecked()) name.setChecked(true); else name.setChecked(false);

Never mind the fact that you can just do (in this case):

name.setChecked(name.isChecked());

The point of the ternary or "conditional" operator is to introduce conditionals into an expression. In other words, this:

int max = a > b ? a : b;

is meant to be shorthand for this:

int max;
if ( a > b ) {
    max = a;
} else {
    max = b;
}

If there is no value being produced, the conditional operator is not a shortcut.

Solution 2 - Java

> I was wondering if it was possible to do a ternary operation but without returning anything.

No it is not possible:

  1. The 2nd and 3rd operands are required to be non-void expressions; i.e. they must produce some actual value.

    > "It is a compile-time error for either the second or the third operand expression to be an invocation of a void method." - JLS 15.25.

  2. A ternary expression is an expression, and cannot be used as a statement.

    > "Certain kinds of expressions may be used as statements by following them with semicolons." ... and the ternary expression is not one of those kinds - JLS 14.8.

If you really, really want to use a ternary expression but not use the value of the expression, then the simplest thing is to assign the value to a dummy variable, and add an annotation to suppress the warning about the variable not being used.

But a better idea is to use a plain if statement.

> If it's not possible in Java is it possible in other languages, if so which ones apply?

I'm a bit rusty, but I believe that C, C++ and Perl all allow arbitrary expressions to be used in places where their values are not used.

Solution 3 - Java

Sometimes, you can use ternary operation on method arguments to solve your request.

name.setChecked(name.isChecked() ? true : false);

By the way, the best solution for your problem is

name.setChecked(name.isChecked());

Solution 4 - Java

I assume the use case in the question is just a poor example because it's equivalent to the following statement:

name.setChecked(name.isChecked());

... which doesn't make sense either. But the intent is clear and there are indeed many relevant use cases.

The only viable and general solution is adding a helper method like this:

static void ternaryVoid(boolean condition, Runnable ifTrue, Runnable ifFalse) {
    (condition ? ifTrue : ifFalse).run();
}

and using it like this:

ternaryVoid(name.isChecked(), () -> name.setChecked(true), () -> name.setChecked(false));

But it loses the elegance of ternary operator and worth the 'effort' only if used by multiple parts of the code and only if nanoseconds don't matter.

> But what's the point of this over an if-else statement? Are you really trying to save 7 characters?

I'm surprised that such statements appear in a form of rhetorical questions. Yes, saving 4 lines and making the code more elegant is important, especially in the context of functional programming.

Moreover, it's at least arguable whether void methods return a complete Void. Essentially, they return a notification of a completed task. This is why logically, ternary expression makes sense equally regardless of whether it returns something or nothing:

condition ? doThis() : doThat();

Here is a real world example of a class which may process millions of incremental updates per second:

public class DataHandler {

    private final TreeMap<Integer, Long> tree = new TreeMap<>();

    public void onUpdate(int price, long amount) {
        if (amount == 0) {
            tree.remove(price);
        } else {
            tree.put(price, amount);
        }
    }
}

If allowed, the onUpdate() method would be a nice ternary expression like this:

public void onUpdate(int price, long amount) {
    (amount == 0) ? tree.remove(price) : tree.put(price, amount); // compilation error
}

Fortunately, in some cases like this, both target methods return values, and these values are of the same type, which is Long in this case. This allows either to make the onUpdate method to return the previous amount at price (which is even useful)

public Long onUpdate(int price, long amount) {
    return (amount == 0) ? tree.remove(price) : tree.put(price, amount);
}

... or alternatively (e.g. in case the method is determined by an interface), to use a dummy variable and suppress its uselessness warning:

public void onUpdate(int price, long amount) {
    @SuppressWarnings("unused")
    Long dummy = (amount == 0) ? tree.remove(price) : tree.put(price, amount);
}

Otherwise, these solutions are not applicable, and as answered by others, doesn't exist. For instance, one may try the following:

Consumer<Void> dummy = (x) -> {};
dummy.accept(/*...*/);

but interestingly, the second line compiles with neither anything nor nothing as an argument.

It seems the best general solution is the above helper method ternaryVoid().

Solution 5 - Java

In java following code isn't possible:

(your-condition) ? (true-statements) : (false-statements)

for sample you can't compile following snipet code :

(1==1) ? System.out.println("") : System.out.println("");

you achieve following compilation error:

The left-hand side of an assignment must be a variable

Solution 6 - Java

You have to return some value and it will not work if you want it to act like a void method which performs some action without a returning a value.

Hope this helps...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTylerKinkadeView Question on Stackoverflow
Solution 1 - JavaMark PetersView Answer on Stackoverflow
Solution 2 - JavaStephen CView Answer on Stackoverflow
Solution 3 - JavaAmir PashazadehView Answer on Stackoverflow
Solution 4 - JavaSergView Answer on Stackoverflow
Solution 5 - JavaSamView Answer on Stackoverflow
Solution 6 - JavaAndroidView Answer on Stackoverflow