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);
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.
I was wondering if it was possible to do a ternary operation but without returning anything.
No it is not possible:
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.
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.
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());
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().
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...
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
Related
I have a method , where I am doing a conditional operation.
But I get a compilation error.
public void hello(){
int x=15;
x==15 ?"Hi":"Bye";
}
If I edit the line and put something mentioned below , the error goes away:
String salutation=x==15 ?"Hi":"Bye;
My question is --is it mandatory to assign the value being returned by a conditional operator to a variable?
x==15 ? "Hi" : "Bye; just floating around does nothing; it's a pure expression. It's like just writing "Hi" in the middle of your code. You need to assign it to a variable for it to actually effect anything.
So yes, it's mandatory in the sense that if you want the ternary to do something, you must assign the result; providing no part of ternary (the condition, and both of the clauses) carries out side effects.
Do you have to store the value returned by conditional operator in
java
Not necessarily, but to simplify you cannot declare it without using it.
You may for example assign it to a variable as you did :
String salutation=x==15 ?"Hi":"Bye;
But you are not forced to store the value in a local variable.
You have other ways to use it.
You may for example pass it as a parameter that waits for a String :
myMethod(x==15 ?"Hi":"Bye");
public void myMethod(String string) {... }
Or you can still use it to apply a method on :
if ((x==15 ?"Hi":"Bye").equals("Bye")){
...
}
You are getting an error because you are not assigning the value based on the condition. Assigning a single variable to one of two states based on a single condition is such a common use of if-else that a shortcut has been devised for it, the conditional operator, ?:. you can't use the shorthand form ?: if the condition doesn't return any value. Your example can be rewritten
public void hello(){
int x = 15;
String salutation;
if (x == 15){
salutation = "Hi";
}else
salutation = "Bye;
}
Using the conditional operator we can rewrite the above example in a single line like this:
public void hello(){
int x = 15;
String salutation = x==15 ?"Hi":"Bye;
}
I do have the following statement:
isEnabled = false;
if(foo(arg) && isEnabled) {
....
}
public boolean foo(arg) {
some really long running code
}
Does it make sense to swap the statements inside the if?
if(isEnabled && foo(arg)) { ... }
Or does the compiler the optimization for me?
Note that the two expressions don't have the same behavior if foo() also has side effects.
If it is manipulating the state of the program, it makes a lot of difference if you always invoke it, or if you invoke it only as a dependency of the value of isEnabled.
For example, consider:
boolean foo(Object arg) {
someLocalVariable = arg;
//do some calculation and return an answer
}
It matters if you always invoke foo(), or if you invoke it only in the case where isEnabled is turned on, resulting in the following two expressions to be completely different from each other:
if (isEnabled && foo(arg)) { ...} //local variable changes only if isEnabled==true
if (foo(arg) && isEnabled) { ...} //local variable always changes
The compiler will not do any optimization in this case.
if(isEnabled && foo(arg)) { ... }
Is always the better approach.
Because i guess you know that when isEnabled is false it will not evaluate foo(arg). And compiler will maintain your sequence of instruction.
Does it make sense to swap the statements inside the if?
Yes. && will only evalute the sub-expressions until one is false. Then the complete exprission will be false, no matter what the other expressions evaluate to.
Since the compiler would have to keep the logic as it is (which includes the order of statements) it won't optimize that.
Suppose foo() has a side effect which some other part of the code relies on, changing the order might break that. Of course this isn't good style in most cases but the compiler can't rely on or enforce style so it has to trust the developer here.
Example:
int x = 0;
boolean foo(int arg) {
x = arg;
return x > 0;
}
void someMethod(int arg) {
boolean isEnabled = false;
if(foo(arg) && isEnabled) {
//whatever
}
//here you use x, I'll simply print it
System.out.println("x=" + x);
}
void someOtherMethod(int arg) {
boolean isEnabled = false;
if(isEnabled && foo(arg)) {
//whatever
}
//here you use x, I'll simply print it
System.out.println("x=" + x);
}
Now calling the methods:
someOtherMethod(7); //foo(7) will not be called so x will still be 0
someMethod(5);
you'll get the output
x=0
x=5
First of all, the Java compiler (which turns java source into bytecode) is pretty dumb. Out of the many optimization techniques known to compiler constructors, just a handful (like constant folding) are implemented by javac.
Whereas the Java just-in-time compiler does many many more things; but even the JIT will not change the order of arguments for you (as that can change the semantics of the underlying program).
Finally, when thinking about this code, performance should not be the motivation behind you changing it. Instead, you should worry about the semantics too. Do you want that foo() is executed (for side effects); or maybe do you not want that foo() runs all the time?
Of course, "foo()" could be doing many many things; and not executing it might gain some performance. But most likely: it will not matter (from a performance perspective).
In other words: stay away from micro-optimisations, see here for backing reasons to that recommendation.
I have the following code,
class Foo<K> {
public <T> T createK() {
return null;
}
public void foo() throws ClassNotFoundException {
K k = (1==1)?null:createK();
}
}
However, it didn't compile. It caused the following compilation error (Oracle Java 7) on the line with the conditional operator:
Type mismatch: cannot convert from Object to K
When I rewrite the foo() method as follows,
public void foo() throws ClassNotFoundException {
K k = null;
if (1==1)
k = null;
else
k = createK();
}
Then it compiles fine. How is this caused and how can I solve it?
Although the conditional operator is not exactly same as if-else conditional, but this is a different issue.
This is a known bug with type inference of generic type parameter with conditional operator which doesn't work as expected.
The solution is to provide explicit type argument:
K k1 = (1==1) ? null : this.<K>createK();
...this would work, however with compiler warning - Dead Code (of course, due to 1 == 1 part). Note, how we need to explicit use this to invoke the method with explicit type argument. Simply doing <K>createK() won't work.
Adding the explicit type argument with method invocation - this.<K>createK(); forces the type T to be inferred as K, which is otherwise inferred as Object.
However, I suspect that your doubt is really related to the type inference. It's just a coincidence that the issue came out to be that. Even though, to get some idea about how conditional operators work in different situations, and what the type of its result is, you can schedule a visit to JLS ยง15.25 - Conditional Operator
No, the ternary (i.e. the ? :) is a very different beast from if ... then ... else.
The ternary is an operator and the two alternatives have to be expressions evaluating to the same type.
if ... then ... else is a convenient programming construct; the bits in between are statements not expressions.
In fact, the entire ternary construct is an expression, whereas the if ... then ... else is itself a statement. (You can assign a value to a ternary; e.g. foo = ... ? ... : ... but foo = if ... then ... else is meaningless and therefore syntatically invalid.)
Your code does not compile because the types of both sides of a conditional expression must match. There is no such requirement for the if statement - in fact, there is no requirement for the two parts to be related to each other in any way, let alone assigning the same variable.
Adding a cast fixes your conditional (demo on ideone):
K k = (1==1)?null:(K)createK();
Those operators are different.
1) In case of if ... then ... else there is no limitations of actions
2) Ternary operator. Using that both sides must have the same type.
You can fix everything with cast:
K k = (1 == 1) ? null : (K)(createK());
Using condition ? valueA : valueB operator is meaningful only if there is an Lvalue,
Lvalue = condition ? valueA : valueB
The exact meannig of this operator can be transformed to an if else statement:
int y,z;
int x= (y==0) ? y+1 : z+3
this ends up to be the same as:
if(y==0)
{
x=y+1;
}else
{
x = z+3;
}
When I need to display a value that might be null/undefined in Javascript, I usually just write:
console.log(a||"");
Or something similar. Is there a similar way to do this in Java other than:
System.out.println(a!=null?a:"");
I think that your System.out.println(a!=null?a:""); is a very clear way to output what you are looking for.
It uses the ternary operator and seems to make sense.
(condition) ? (if true) : (if false);
The best you can do besides using the ternary operator is to create a very short method to do the same. Perhaps "ns" for "nullable string":
public static String ns(String nullableString) {
return nullableString == null ? "" : nullableString;
}
Then you can write "System.out.println(ns(a));" However, the ternary operator is clearer - I would only do something like the above if I were doing this all over the place.
You have ternaries:
a != null ? a : ""
There isn't, as the others answers suggest. That is because in JS, boolean operators don't necessarily return booleans, they return the value of the object that caused the expression to short-circuit. However, in Java, as in C and other languages, boolean operators always return boolean, so you don't have that convenient way of defaulting a value a = b || c or to prevent a null pointer a = b && b.getValue()
You can do a function that doesn't print null when its null.
I don't know java but a prototype will be
function safePrint(object a)
{
System.out.println(a!=null?a:"");
}
and then just write
safePrint(a);
Although if you are looking for short code use an interpreted language like javascript or perl. compiled languages like java is just not meant for fast and short coding.
If the variable is not initialized, java will not compile. Undefined is unacceptable in Java.
If you have a variable named "blueberry" and you want to display the value on the console, you can do this:
System.out.println(blueberry);
This code will display "null" on the console if blueberry is null.
Here is a simple demonstration
public class Outty
{
public static void main(String[] args)
{
String blueberry = null;
System.out.println(blueberry);
blueberry = "7";
System.out.println(blueberry);
}
}
Is a switch statement the fastest way to implement operator interpretation in Java
public boolean accept(final int op, int x, int val) {
switch (op) {
case OP_EQUAL:
return x == val;
case OP_BIGGER:
return x > val;
case OP_SMALLER:
return x < val;
default:
return true;
}
}
In this simple example, obviously yes. Now imagine you have 1000 operators. would it still be faster than a class hierarchy? Is there a threshold when a class hierarchy becomes more efficient in speed than a switch statement? (in memory obviously not)
abstract class Op {
abstract public boolean accept(int x, int val);
}
And then one class per operator.
EDIT:
Sorry, I should have been more specific by the look of the answers.
The Operator is totally unknown and I'm using JDk 1.4. No choice. No enums. No Closures. :(
The operator is chosen by the user among many many many choices. For simplicity sake, Imagine a GUI List with 1000 operations, when user selects one, op code of the switch statement is chosen. Using a class hierarchy, user would select a class.
I'm asking this question because someone must have tested it before. I don't feel like creating 1000 classes and 1000 bogus op codes to test it. If nobody has done it. I will test it and report the results, if they may have any meaning at all.
EDIT:
Okay, since you have to use JDK 1.4, my original answer is a no-go (left below for reference). I would guess that the switch is not as fast as the abstract class-based solution when you're just looking at the apply(which,a,b) vs which.apply(a,b) call. You'll just have to test that.
However, when testing, you may also want to consider start-up time, memory footprint, etc.
ORIGINAL:
public enum OPERATION {
// ...operators+implementation, e.g.:
GREATER_THAN { public boolean apply(int a, int b) { return a > b; } };
public abstract boolean apply(int a, int b);
}
usage:
OPERATION x = //..however you figure out which
boolean result = x.apply(a,b);
this is one of the case uses in Effective Java for enums. It works exactly like the switch, only less confusing.
Because of the way a switch statement is usually implemented in a jvm, with a lookup table, it is likely it is going to be faster, with a small or big number of operators. This is just guessing; to have a definite answer you need to benchmark it on the system it is intended to run.
But, that is just a micro-optimization which you shouldn't care about unless profiling shows that it could really make a difference. Using integers instead of a specific class (or enum) makes code less readable. A huge switch statement with 1000 cases is a sign of a bad design. And that will have an influence on the code that is using the operators; less readable, more bugs, harder to refactor,...
And to get back to performance, which seems to be the goal here. In hard to read, badly designed code, the changes required for macro-optimizations become harder. And those optimizations are usually a lot more important than micro-optimizations like this switch.
I do not know what is fastest, nor do I think there are any guarantees. Optimization of code is very much dependent on both compiler and runtime.
I do think that it's hard to beat a switch statement. Due to the limitations Java puts on the types which can be switched it can fairly easily be compiled to a lookup table, which is about the fastest access you can get.
Use a table-driven method, as a previous poster pointed out you may use the operator as the index of an array. The value stored in the array could be an instance of a class that performs the comparison. The array can be initialized statically, or better on-demand (lazy loading pattern).
e.g.
// Interface and classes
interface Operator {
boolean operate(int x, int y);
}
class EqualsOperator implements Operator {
boolean operate(int x, int y){
return x==y;
}
}
class NotEqualsOperator implements Operator {
boolean operate(int x, int y){
return x=!y;
}
}
...
// Static initialization
Operator[] operators = new Operator[n];
operator[0] = new EqualsOperator();
operator[1] = new NotEqualsOperator();
...
// Switch
public boolean accept(final int op, int x, int val) {
operator[op].operate(x,val);
}
If the calling method already has to decide which operator value to use and call accept(), then the fastest thing would be to do the comparisons inline in that same calling method.
Alternatively, use three methods (or strategies):
public boolean acceptGreater(int x, int val) {
return x > val;
}
public boolean acceptLess(int x, int val) {
return x < val;
}
public boolean acceptEquals(int x, int val) {
return x == val;
}
I wouldn't look at this purely from a raw performance point of view, but I'd evaluate this as a refactoring candidate, see c2:Refactor Mercilessly. I liked the answer given to code resuability:
If you repeat it once, copy it.
If you repeat it twice, refactor it.
I'd identify the adding of multiple case statements as repetition, and then I'd refactor to implement the Strategy Pattern.
I'd name the operator classes with a strategy suffix, and implement the execute method.
I've always found that the java switch statement is not as powerful as I need. In his last release lambdaj implements it with a smart use of closure and Hamcrest matcher.