I'm wondering if there's a way to convert a boolean to an int without using if statements (as not to break the pipeline). For example, I could write
int boolToInt( boolean b ){
if ( b )
return 1
return 0
But I'm wondering if there's a way to do it without the if statement, like Python's
bool = True
num = 1 * ( bool )
I also figure you could do
boolean bool = True;
int myint = Boolean.valueOf( bool ).compareTo( false );
This creates an extra object, though, so it's really wasteful and I found it to be even slower than the if-statement way (which isn't necessarily inefficient, just has the one weakness).
You can't use a boolean other than in a if. However it does not mean that there will be a branch at the assembly level.
If you check the compiled code of that method (by the way, using return b ? 1 : 0; compiles to the exact same instructions), you will see that it does not use a jump:
0x0000000002672580: sub $0x18,%rsp
0x0000000002672587: mov %rbp,0x10(%rsp) ;*synchronization entry
0x000000000267258c: mov %edx,%eax
0x000000000267258e: add $0x10,%rsp
0x0000000002672592: pop %rbp
0x0000000002672593: test %eax,-0x2542599(%rip) # 0x0000000000130000
; {poll_return}
0x00000000025b2599: retq
Note: this is on hotspot server 7 - you might get different results on a different VM.
Use the ?: operator: ( b ? 1 : 0 )
You can use the ternary operator:
return b ? 1 : 0;
If this is considered an "if", and given this is a "puzzle", you could use a map like this:
return new HashMap<Boolean, Integer>() {{
put(true, 1);
put(false, 0);
}}.get(b);
Although theoretically the implementation of HashMap doesn't need to use an if, it actually does. Nevertheless, the "if" is not in your code.
Of course to improve performance, you would:
private static Map<Boolean, Integer> map = new HashMap<Boolean, Integer>() {{
put(true, 1);
put(false, 0);
}};
Then in the method:
return map.get(b);
Otherwise, you could use the Apache Commons BooleanUtils.toInteger method which works like a charm...
// Converts a boolean to an int specifying the conversion values.
static int toInteger(boolean bool, int trueValue, int falseValue)
// Converts a Boolean to an int specifying the conversion values.
static int toInteger(Boolean bool, int trueValue, int falseValue, int nullValue)
I found a solution by framework. Use compare for Boolean.
// b = Your boolean result
// v will be 1 if b equals true, otherwise 0
int v = Boolean.compare(b, false);
This is not directly possible, not in Java anyway. You could consider directly using an int or byte instead of a boolean if you really need to avoid the branch.
It's also possible that the VM is smart enough to eliminate the branch (the if or ?:) itself in this case, as the boolean's internal representation is quite likely to be the literal 1 or 0 anyway. Here is an article on how to examine the generated native machine code for the Oracle JDK, and if you need speed, make sure you're using the "server" JVM as it performs more aggressive optimization than the "client" one.
I can't say I recommend this. It's both slower than the ternary operator by itself, and it's too clever to be called good programming, but there's this:
-Boolean.FALSE.compareTo(value)
It uses the ternary under the covers (a couple of method calls later), but it's not in your code. To be fair, I would be willing to bet that there's a branch somewhere in the Python execution as well (though I probably only bet a nickel ;) ).
Since you want no if / else solution your expression is perfect, though I would slightly change it
int myint = Boolean.valueOf( bool ).compareTo( Boolean.FALSE );
There is no object creation involved, Boolean.valueOf(boolean b) returns either Boolean.TRUE or Boolean.FALSE, see API
A reasonable alternative to ising to the ternary to avoid an "if":
private static Boolean[] array = {false, true};
int boolToInt( boolean b ){
return Arrays.binarySearch(array, b);
}
Note that I consider this s "puzzle" question, so if coding it myself i would use the ternary..
You can try using ternary operator like this
int value = flag ? 1 : 0;
Nowadays, jdk has delivered a useful Utils method: BooleanUtils.toInteger()
In the source code, the method that jdk realize it must be efficient:
public static int toInteger(boolean bool) {
return bool ? 1 : 0;
}
So, I think the most votes answer is very great, return bool ? 1 : 0 is the best practice.
Example Code to use BooleanUtils as followed:
BooleanUtils.toInteger(false);
int ansInt = givenBoolean ? 1 : 0;
Related
In logic expressions remaining part would be skipped if it is unnecessary
boolean b = false && checkSomething( something)
//checkSomething() doesn't get called
What is a good way to achieve the same with arithmetic expressions ?
int i = 0 * calculateSomethig ( something )
It is possible to add ifs before * . But is there a more elegant way to solve this problem? Without of adding much stuff into expression, so that expression itself would look as close to original as possible
Why i do not want to use ifs?
from
return calculateA() * calculateB()
it'll become bulky and unclear
int result
int a = calculateA();
if (a!=0) {
result = a*calculateB()
}else{
result = 0
}
return result
8 lines of code instead of 1,
those expressions might be more complex than a*b
those expressions represent business logic so i want to keep them
clear and easily readable
there might be whole bunch of them
Why do i bother with this at all?
Because calculation methods might be expensive
uses values form other places, where searches and sorts are happening
lots of those expressions can be executed at once ( after user event and user should see result "instantly"
P( *0 in expression ) >0.5
&& and || are called short-circuit operators because they don't evaluate if the JVM will find the value of the whole expression without evaluating the whole expression. For example, the JVM does not have to evaluate the second part of the following expression to tell it evaluates to true:
6 == (2 + 4) || 8 == 9
The JVM does not have to evaluate all of the following expression either to tell it evaluates to false:
9 == 8 && 7 == 7
The multiplication operator (*) is not a short-circuit operator. And so, it does not behave that way. You can do this as you mentioned using if statements. There is no predefined way to do this.
You can create a structure that uses lambdas to evaluate its arguments lazily:
class LazyMul implements IntSupplier {
private final IntSupplier [] args;
private LazyMul(IntSupplier[] args) {
//argument checking omitted for brevity :)
this.args = args;
}
public static LazyMul of(IntSupplier ... args) {
return new LazyMul(args);
}
#Override
public int getAsInt() {
int res = 1;
for (IntSupplier arg: args) {
res *= arg.getAsInt();
if (res == 0)
break;
}
return res;
}
}
Of course this is even longer but using it is as simple as LazyMul.of(this::calculateA, this::calculateB), so if you use it several times, it's better than having an if every time around.
Unfortunately with complicated (particularly nested) expressions readability suffers, but these are the limitations of Java as a language.
I want to use guava iterator or java8 foreach(may be lambda expression) nested for loop and process some statements and return a long variable. Here is my code in native java. Please excuse my code may not efficient. I read over net accessing non final variables inside new java 8 foreach is not possible.
Long x = Long.valueOf(0);
Long y = Long.valueOf(0);
for(FirstLevel first : Levels)
{
if(first.getSecondLevels() == null)
{
x= x + getSomeValue(first);
}
for (SecondLevel second : first.getSecondLevels())
{
y = y + getSomeValue(second);
}
}
return x + y;
I have tried but unable to return the values. Thanks in advance for help!
Couple things:
Before approaching "refactoring" like that one you ask, I really strongly recommend learning more "pure" Java (which I assume is the case here, #javalearner). For example you can use long literals instead of manually boxing values:
long x = 0L;
long y = 0L;
Anyway...
using Guava won't help here - this is the imperative way of doing it, and with Java 7 + Guava you'd have to write awkward anonymous classes (i.e. Functions), which without language support is painful. Which brings me to...
Java 8 and Streams. This is probably the best way to go, but first you have to fix (?) your code and define actual problem - for example this statement x= x + getSomeValue(x); evaluates x each time and does not take FirstLevel into account (same is true for y and SecondLevel), so I assume what you really meant was x =+ getSomeValue(firstLevel);.
Having all that said - please be more specific what your problem really is.
EDIT:
After your clarification, using streams your code could look like this:
final long sum = levels.stream()
.mapToLong(first -> getSomeValue(first) + first.getSecondLevels().stream().mapToLong(this::getSomeValue).sum())
.sum();
or with some helper method:
final long s = levels.stream()
.mapToLong(first -> getSomeValue(first) + getSecondLevelSum(first))
.sum();
private long getSecondLevelSum(final FirstLevel first) {
return first.getSecondLevels().stream().mapToLong(this::getSomeValue).sum();
}
First of all, there is no sense in using boxed Long values and even if you once need a boxed value, you don’t need to invoke Long.valueOf, Java already does that for you when converting a long primitive to a boxed Long object.
Further, since adding long values does not depend on the order of summands, there is no reason to maintain two variable throughout the operation, when you will add them at the end anyway:
long result=0;
for(FirstLevel first: Levels) {
result += getSomeValue(first);
for(SecondLevel second: first.getSecondLevels()) {
result += getSomeValue(second);
}
}
return result;
Note that the operator += does the same as result = result + … here, but avoids the repetition of the target operand.
Assuming that both, Levels and the result of getSecondLevels, are collections you can write the same as Stream operation as
return Levels.stream()
.mapToLong(first ->
getSomeValue(first) + first.getSecondLevels().stream()
.mapToLong(second -> getSomeValue(second)).sum())
.sum();
or, alternatively
return Levels.stream()
.flatMapToLong(first -> LongStream.concat(
LongStream.of(getSomeValue(first)),
first.getSecondLevels().stream().mapToLong(second -> getSomeValue(second))))
.sum();
If Levels is an array, you have to replace Levels.stream() with Arrays.stream(Levels) and likewise, if getSecondLevels() returns an array, you have to replace first.getSecondLevels().stream() with Arrays.stream(first.getSecondLevels())
I have a string that I would like to convert into an integer before storing it as a property of an object. Although I can use regular if statements, I wanted to use a ternary operation to build my understanding of it. Here is the code I've tried
field_num = (((boolean bool_is_int = is_integer(string)) == true) ? (Integer int = Integer.parseInt(string)) : null);
What I'm trying to do (very basically) is set "field_num" (which is of type int) to the value of "string" if it is equal to an integer (by first converting it). is_integer is a function I have to check if a string is equal to an integer. It returns a boolean value.
Thanks for any help.
I would do something like this:
Integer theint = is_integer(thestr) ? Integer.parseInt(thstr) : null;
You cannot assign NULL to an intrinsic int but you can to an Integer object. Typically, of course, you'd simply rely on the parseInt() call throwing an exception rather than explicitly testing for integerness of the string beforehand.
field_num = is_integer(string) ? Integer.parseInt(string): -1;
In plain english this says if 'string' is an integer then parse string for the int and set it to field_num otherwise, set it to -1. -1 is arbitrary. you should instead use a number that is invalid for field_num.
You do not need is_integer(string) == true because that evaluates to the same thing as is_integer(string). You also don't need to set the boolean bool_is_int because unless you actually want that value later in the program.
You should just use an if/else statement. The Ternary operator is useful when you you want to set a variable to one of two values based on a condition. In your example, you don't want to set the value if the string is not an integer so ternary doesn't fit the situation well.
Keep it simple :)
int field_num = isInt(string) ? Integer.parseInt(string) : Integer.MAX_VALUE;
if (field_num == Integer.MAX_VALUE) {
// error; string is not a valid representation of int
}
To determine Whether a String represents an int value :
public static boolean isInt(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
}
return true;
}
[Corrected]
Learn one thing at a time.
First, the ?: operator (more often referred to as the conditional operator, or the if/else operator; "ternary" just means it takes three arguments, and it's the only C operator that does so, hence the confusion)...
field_num = is_integer(string) ? Integer.parseInt(string) : null;
Ahhh. So field_num is an Integer. Would have help if you'd said that.
Second: Assignment-in-passing. If you don't know that you need to do this, and you can't make it perfectly obvious what you're doing and why, DON'T. It's hard to read, and it's rarely appropriate.
Also, "int" is not a legal variable name.
But if you insist:
Integer myint;
boolean bool_is_int;
field_num = (bool_is_int = is_integer(string)) ? (myint = Integer.parseInt(string)) : null;
What's myint's value in the false/else case? It's left as whatever it had been set to previously. This might be what you intended, but it's very hard for someone reading your code to understand.
In most cases, unless the ?: is a very simple one that can be read at a glance -- (foo!=null) ? foo.doSomething() : defaultValue -- you're better off using a real if/then/else statement. It's likely to be just as efficient after the compiler and JIT are done with it, and it'll be a lot easier to maintain.
This might sound weird but I am struggling with this bug for past 2 days.
I have a boolean array in java that is initialised using a Random boolean generator.
After that the boolean array is acted upon by a function in C (called using JNI) and the modified boolean array is returned to java. When I hand over the boolean array to C, it is converted to unsigned char and converted back to jbooleanArray before being handed back to java.
Now I run the following code (there is a for loop over i):
if(chosen_packet[i] == false)
{
pkt.first[i] = 0;
System.out.print(chosen_packet[i]);
}
if(chosen_packet[i] == true)
{
pkt.first[i] = 1;
System.out.print(chosen_packet[i]);
}
The problem is that sometimes when chosen_packet[i] is true it still does not enter the second if condition. This happens sometimes and sometimes the code works just fine. When I print chosen_packet[i] in such a case it is printed as true yet it does not enter the second if condition. What could be the possible reason for this seeming corruption of the boolean array ?
EDIT: This is how I convert the boolean array to unsigned char in C:
jboolean *element = (*env)->GetBooleanArrayElements(env,chosen_packet,0);
for(j = 0; j < sz; j++)
src_pkt[j] = (unsigned char)element[j];
This src_pkt is acted upon and then I convert it back to jboolean .
EDIT2: This is how I convert the unsigned char array back to jboolean:
jbooleanArray arr = (*env)->NewBooleanArray(env,sz);
(*env)->SetBooleanArrayRegion(env,arr,0,sz,src_pkts);
(*env)->DeleteLocalRef(env,arr);
It's normal that if the boolean is true it does not enter in the first if since you are checking for it to be false in its condition.
Your code can be simplified to (you should use if/else instead of two if checking for the different conditions).
if (chosen_packet[i]) {
pkt.first[i] = 1;
} else {
pkt.first[i] = 0;
}
System.out.print(chosen_packet[i]);
or even
pkt.first[i] = chosen_packet[i] ? 1 : 0;
System.out.print(chosen_packet[i]);
Edit
If your program does not enter the second if, it means that the the var chosen_packet[i] is not true, you could use a debugger to verify what is the real value.
As stated by fredcrs, are you sure that chosen_packet[i] is of type boolean?
Java boolean is usually implemented as single byte. So it is possible that there is a bug in your C code that causes the boolean to be neither true nor false. In that case you may encounter undefined behavior.
Note that simply casting unsigned char to jboolean as in(jboolean) src_pkt[j] does not normalize it. You have to use src_pkt[j] ? JNI_TRUE : JNI_FALSE.
Still I believe you have to post more of relevant parts of your JNI code.
I've seen this before in code, but forgotten it. Basically it toggles a boolean variable. If it's true, it'll set to false and vice-versa. But unfortunately forgot the syntax.
It's basically a one liner for this:
if (myVar) {
myVar = false;
} else {
myVar = true;
}
It's something like this, but don't know what it's called or the correct syntax of it:
myVar = myVar : false ? true;
How about
myVar = !myVar
?
myVar = myVar ? false : true; is using the conditional operator.
You can just do this though
myVar = !myVar;
Another option is XOR:
myVar ^= true;
It's notable in that only the LHS of the assignment ever changes; the right side is constant and will toggle any boolean variable. Negation's more self-documenting IMO, though.
What you are thinking of is the conditional operator:
myVar = myVvar ? false : true;
(As you see, a lot of people call this "the ternary operator", but that only means that it is an operator with three operands. As it happens, there is only one operator with three operands in this language, but it still says nothing about what the operator does.)
It's of course easier to use the negation operator:
myVar = !myVar;
The smallest code I can think of at the moment. I don't know what its called (if it has a name, as you seem to suggest)
myVar = !myVar
What you're talking about is the "ternary" or "conditional" operator, which does an inline substitution as per a condition.
The syntax is:
condition ? trueValue : falseValue
I usually throw parentheses around my condition, sometimes around the whole conditional operator. Depends on how much I'm trying to delineate it from everything else.
So for example, suppose you want to return the larger of two numbers:
public int max(int a, int b)
{
return (a > b) ? a : b;
}
Notice that it can be substituted into the middle of something else.
Okay, now let's tackle your actual question about toggling a boolean type.
myVar = (myVar) ? false : true;
is how you would do it with the conditional operator. (Again, parentheses aren't required, I just favor them.)
But there's a simpler way to toggle the boolean... using the logical NOT ("!") operator:
myVar = !myVar;
Keep it simple. :-)
if(myVar == true)
{
myVar = false;
}
else if (myVar == false)
{
myVar = true;
}
else
{
myVar = FILE_NOT_FOUND
}
This also works :P
v=v?!v:!v;
There is a ternary operator (wikipedia). Which allows you to write a condensed if-else statement like in the second example.
In java:
myVar = (myVar) ? true : false;
There is also the NOT operator, which toggles a boolean variable. In java that is !. I believe that is what you want.
myVar = !myVar;
public boolean toggle(boolean bool)
{
return !bool;
}
I recently (on my own) found a similar answer to one already stated here. However, the simplest and shortest (non-repeating variable name with least code) answer is:
formControl.disabled ^= 1;
This works best in JavaScript when wanting to toggle boolean, DOM-based attributes (for example, a form control/input's disabled property -- going from a non-editable to edit state). After much searching (with no result that I liked) and some trial and error, I found my solution to be the simplest (however, true instead of a 1 would be clearer -- as was previously posted).
Since this syntax isn't very clear, immediately, I would not advise using it very often (I believe it is appropriate when the variable or property makes the context obvious). I have posted this response (instead of making it a comment) because the context in which the XOR bitwise self-assignment should be used is very important. This "trick" should mostly be avoided when considering best practices.
As others have noted, there are two ways to negate something: "lvalue = !lvalue;" and "lvalue ^= 1;". It's important to recognize the differences.
Saying "lvalue = !lvalue" will cause lvalue to be set to 1 if it was zero, and 0 if it was set to anything else. The lvalue will be evaluated twice; this is not a factor for simple variables, but saying "someArray[index1][index2][index3][index4] = !someArray[index1][index2][index3][index4]" could slow things down.
Saying "lvalue ^= 1;" will cause lvalue to be set to 1 if it was 0, 0 if it was 1, and something else if it was neither zero nor 1. The lvalue need only be specified or evaluated once, and if the value is known to be either zero or 1, this form is likely to be faster.
Too bad there's no auto-negate operator; there are times such a thing would be handy.
You can also use the binary form of negation as shown here.
if ((v == true) && !(v = false)) {
v != true; /* negate with true if true. */
} else {
v =! false; /* negate with false if false. */
}