Ternary Operator - Java

How does the ternary operator work

The operator you used there is called a ternary operator and it works almost the same way an if-else statement works. Consider the statement below:

int min = (a < b) ? a : b;

What this means is: Evaluate the value of (a < b), if it's true, the value of min is a, otherwise, the value of min is b. It can be related to the if-else statement this way: If (a < b) is true: min = a; else: min is b.

Back to your question now....

em.remove(em.contains(student) ? student : em.merge(student));

This means if em.contains(student) is true, then perform em.remove(student), however if it's false, then perform em.remove(em.merge(student)).

PS:

Obviously, in many practical cases that involve giving a variable a value based on a two-way condition, this can be a subtle replacement for if-statement. There is great argument about the "more efficient" method as seen in this post but I personally prefer to use the ternary operator because of it's relatively short syntax length and readability.

I hope this helps.. Merry coding!

Java ternary operator on simple binary search problem

The conditional operator can only be used as part of an expression. An expression cannot stand on its own, but needs to be part of a statement. Assigning a variable is a statement. Computing a value and not storing it, is not. Convert the expression to an statement:

int ans = (nums[middle] < target) ? (left = middle + 1) : (right = middle - 1);

Becomes:

if (nums[middle] < target) {
left = middle + 1;
} else {
right = middle - 1;
}

If you want to save a few key strokes:

if (nums[middle] < target) left = middle + 1;
else right = middle - 1;

Relevant links to the JLS:

  • JLS 14.5 Statements
  • JLS 14.8 Expression Statements
  • JLS 15.25 Conditional Operator

ternary operator do nothing in else part

        MaleCounter += arr[0].equals("male") ? 1 : 0;
FemaleCounter += arr[0].equals("female") ? 1 : 0;
StateCounterIn += arr[1].equals("in") ? 1 : 0;
StateCounterOut += arr[1].equals("out") ? 1 : 0;

A ternary expression must deliver a result. Also ++ inside and then assigment is overkill.

replace two ternary operator by java 8 optional expression

Try this.

String result = Optional.ofNullable(valueA)
.map(s -> s.length() < 3 ? "0" + s : s)
.orElse(valueB);

return multiple values from a single ternary operator in java

In the same way as you can't write (int a, String b) = (1, "success");, no, you can't do this in Java.

All you can do - if you want them as separate variables - is to use an if statement:

int a;
String b;
if (condition) {
a = 1;
b = "success";
} else {
a = 0;
b = "error";
}

If you would accept having a and b as fields in a class (which I'm not going to define here), you could write it as something like:

Result r = condition ? Result.create(1, "success") : Result.create(0, "error");

You can then unpack a and b from r as required.

Why is a ternary operator with two constants faster than one with a variable?

First, let's rewrite the benchmark with JMH to avoid common benchmarking pitfalls.

public class FloatCompare {

@Benchmark
public float cmp() {
float num = ThreadLocalRandom.current().nextFloat() * 2 - 1;
return num < 0 ? 0 : num;
}

@Benchmark
public float mul() {
float num = ThreadLocalRandom.current().nextFloat() * 2 - 1;
return num * (num < 0 ? 0 : 1);
}
}

JMH also suggests that the multiplication code is a way faster:

Benchmark         Mode  Cnt   Score   Error  Units
FloatCompare.cmp avgt 5 12,940 ± 0,166 ns/op
FloatCompare.mul avgt 5 6,182 ± 0,101 ns/op

Now it's time to engage perfasm profiler (built into JMH) to see the assembly produced by JIT compiler. Here are the most important parts of the output (comments are mine):

cmp method:

  5,65%  │││  0x0000000002e717d0: vxorps  xmm1,xmm1,xmm1  ; xmm1 := 0
0,28% │││ 0x0000000002e717d4: vucomiss xmm1,xmm0 ; compare num < 0 ?
4,25% │╰│ 0x0000000002e717d8: jbe 2e71720h ; jump if num >= 0
9,77% │ ╰ 0x0000000002e717de: jmp 2e71711h ; jump if num < 0

mul method:

  1,59%  ││  0x000000000321f90c: vxorps  xmm1,xmm1,xmm1    ; xmm1 := 0
3,80% ││ 0x000000000321f910: mov r11d,1h ; r11d := 1
││ 0x000000000321f916: xor r8d,r8d ; r8d := 0
││ 0x000000000321f919: vucomiss xmm1,xmm0 ; compare num < 0 ?
2,23% ││ 0x000000000321f91d: cmovnbe r11d,r8d ; r11d := r8d if num < 0
5,06% ││ 0x000000000321f921: vcvtsi2ss xmm1,xmm1,r11d ; xmm1 := (float) r11d
7,04% ││ 0x000000000321f926: vmulss xmm0,xmm1,xmm0 ; multiply

The key difference is that there's no jump instructions in the mul method. Instead, conditional move instruction cmovnbe is used.

cmov works with integer registers. Since (num < 0 ? 0 : 1) expression uses integer constants on the right side, JIT is smart enough to emit a conditional move instead of a conditional jump.

In this benchmark, conditional jump is very inefficient, since branch prediction often fails due to random nature of numbers. That's why the branchless code of mul method appears faster.

If we modify the benchmark in a way that one branch prevails over another, e.g by replacing

ThreadLocalRandom.current().nextFloat() * 2 - 1

with

ThreadLocalRandom.current().nextFloat() * 2 - 0.1f

then the branch prediction will work better, and cmp method will become as fast as mul:

Benchmark         Mode  Cnt  Score   Error  Units
FloatCompare.cmp avgt 5 5,793 ± 0,045 ns/op
FloatCompare.mul avgt 5 5,764 ± 0,048 ns/op

Is it possible to use break with ternary operator

Is it possible use the break and continue words with ternary operator?

No. It doesn't really make sense, and thus isn't supported.

EDIT

The following code has been added to the question:

int variable = 5

for (int i = 0; i < 10; i++)
variable = (variable == 5) ? break : variable
System.out.println(variable)

variable = (variable == 5) ? break : variable isn't valid, but it were, I think that could be simplified to this:

int variable = 5

for (int i = 0; i < 10; i++)
if(variable == 5) { break; }
System.out.println(variable)

The "else" condition in your proposed ternary operator would be assigning the variable its own value, which of course is a step you can skip.

Presumably your actual scenario is more sensible than the way that sample code is written. You wouldn't want i < 10 if your intent was to quit when you got to 5.



Related Topics



Leave a reply



Submit