Shortcut "or-assignment" (|=) operator in Java - java

I have a long set of comparisons to do in Java, and I'd like to know if one or more of them come out as true. The string of comparisons was long and difficult to read, so I broke it up for readability, and automatically went to use a shortcut operator |= rather than negativeValue = negativeValue || boolean.
boolean negativeValue = false;
negativeValue |= (defaultStock < 0);
negativeValue |= (defaultWholesale < 0);
negativeValue |= (defaultRetail < 0);
negativeValue |= (defaultDelivery < 0);
I expect negativeValue to be true if any of the default<something> values are negative. Is this valid? Will it do what I expect? I couldn't see it mentioned on Sun's site or stackoverflow, but Eclipse doesn't seem to have a problem with it and the code compiles and runs.
Similarly, if I wanted to perform several logical intersections, could I use &= instead of &&?

The |= is a compound assignment operator (JLS 15.26.2) for the boolean logical operator | (JLS 15.22.2); not to be confused with the conditional-or || (JLS 15.24). There are also &= and ^= corresponding to the compound assignment version of the boolean logical & and ^ respectively.
In other words, for boolean b1, b2, these two are equivalent:
b1 |= b2;
b1 = b1 | b2;
The difference between the logical operators (& and |) compared to their conditional counterparts (&& and ||) is that the former do not "shortcircuit"; the latter do. That is:
& and | always evaluate both operands
&& and || evaluate the right operand conditionally; the right operand is evaluated only if its value could affect the result of the binary operation. That means that the right operand is NOT evaluated when:
The left operand of && evaluates to false
(because no matter what the right operand evaluates to, the entire expression is false)
The left operand of || evaluates to true
(because no matter what the right operand evaluates to, the entire expression is true)
So going back to your original question, yes, that construct is valid, and while |= is not exactly an equivalent shortcut for = and ||, it does compute what you want. Since the right hand side of the |= operator in your usage is a simple integer comparison operation, the fact that | does not shortcircuit is insignificant.
There are cases, when shortcircuiting is desired, or even required, but your scenario is not one of them.
It is unfortunate that unlike some other languages, Java does not have &&= and ||=. This was discussed in the question Why doesn't Java have compound assignment versions of the conditional-and and conditional-or operators? (&&=, ||=).

It's not a "shortcut" (or short-circuiting) operator in the way that || and && are (in that they won't evaluate the RHS if they already know the result based on the LHS) but it will do what you want in terms of working.
As an example of the difference, this code will be fine if text is null:
boolean nullOrEmpty = text == null || text.equals("")
whereas this won't:
boolean nullOrEmpty = false;
nullOrEmpty |= text == null;
nullOrEmpty |= text.equals(""); // Throws exception if text is null
(Obviously you could do "".equals(text) for that particular case - I'm just trying to demonstrate the principle.)

You could just have one statement. Expressed over multiple lines it reads almost exactly like your sample code, only less imperative:
boolean negativeValue
= defaultStock < 0
| defaultWholesale < 0
| defaultRetail < 0
| defaultDelivery < 0;
For simplest expressions, using | can be faster than || because even though it avoids doing a comparison it means using a branch implicitly and that can be many times more expensive.

Though it might be overkill for your problem, the Guava library has some nice syntax with Predicates and does short-circuit evaluation of or/and Predicates.
Essentially, the comparisons are turned into objects, packaged into a collection, and then iterated over. For or predicates, the first true hit returns from the iteration, and vice versa for and.

If it is about readability I've got the concept of separation tested data from the testing logic. Code sample:
// declare data
DataType [] dataToTest = new DataType[] {
defaultStock,
defaultWholesale,
defaultRetail,
defaultDelivery
}
// define logic
boolean checkIfAnyNegative(DataType [] data) {
boolean negativeValue = false;
int i = 0;
while (!negativeValue && i < data.length) {
negativeValue = data[i++] < 0;
}
return negativeValue;
}
The code looks more verbose and self-explanatory. You may even create an array in method call, like this:
checkIfAnyNegative(new DataType[] {
defaultStock,
defaultWholesale,
defaultRetail,
defaultDelivery
});
It's more readable than 'comparison string', and also has performance advantage of short-circuiting (at the cost of array allocation and method call).
Edit:
Even more readability can be simply achieved by using varargs parameters:
Method signature would be:
boolean checkIfAnyNegative(DataType ... data)
And the call could look like this:
checkIfAnyNegative( defaultStock, defaultWholesale, defaultRetail, defaultDelivery );

It's an old post but in order to provide a different perspective for beginners, I would like give an example.
I think the most common use case for a similar compound operator would be +=. I'm sure we all wrote something like this:
int a = 10; // a = 10
a += 5; // a = 15
What was the point of this? The point was to avoid boilerplate and eliminate the repetitive code.
So, next line does exactly the same, avoiding to type the variable b1 twice in the same line.
b1 |= b2;

List<Integer> params = Arrays.asList (defaultStock, defaultWholesale,
defaultRetail, defaultDelivery);
int minParam = Collections.min (params);
negativeValue = minParam < 0;

|| logical boolean OR
| bitwise OR
|= bitwise inclusive OR and assignment operator
The reason why |= doesn't shortcircit is because it does a bitwise OR not a logical OR.
That is to say:
C |= 2 is same as C = C | 2
Tutorial for java operators

Related

How to correctly remove redundancy in compound booleans in Java? [duplicate]

Why can't do you this if you try to find out whether an int is between to numbers:
if(10 < x < 20)
Instead of it, you'll have to do
if(10<x && x<20)
which seems like a bit of overhead.
One problem is that a ternary relational construct would introduce serious parser problems:
<expr> ::= <expr> <rel-op> <expr> |
... |
<expr> <rel-op> <expr> <rel-op> <expr>
When you try to express a grammar with those productions using a typical PGS, you'll find that there is a shift-reduce conflict at the point of the first <rel-op>. The parse needs to lookahead an arbitrary number of symbols to see if there is a second <rel-op> before it can decide whether the binary or ternary form has been used. In this case, you could not simply ignore the conflict because that would result in incorrect parses.
I'm not saying that this grammar is fatally ambiguous. But I think you'd need a backtracking parser to deal with it correctly. And that is a serious problem for a programming language where fast compilation is a major selling point.
Because that syntax simply isn't defined? Besides, x < y evaluates as a bool, so what does bool < int mean? It isn't really an overhead; besides, you could write a utility method if you really want - isBetween(10,x,20) - I wouldn't myself, but hey...
It's just the syntax. '<' is a binary operation, and most languages don't make it transitive. They could have made it like the way you say, but then somebody would be asking why you can't do other operations in trinary as well. "if (12 < x != 5)"?
Syntax is always a trade-off between complexity, expressiveness and readability. Different language designers make different choices. For instance, SQL has "x BETWEEN y AND z", where x, y, and z can individually or all be columns, constants, or bound variables. And I'm happy to use it in SQL, and I'm equally happy not to worry about why it's not in Java.
You could make your own
public static boolean isBetween(int a, int b, int c) {
return b > a ? c > a && c < b : c > b && c < a;
}
Edit: sorry checks if c is between a and b
The inconvenience of typing 10 < x && x < 20 is minimal compared to the increase in language complexity if one would allow 10 < x < 20, so the designers of the Java language decided against supporting it.
COBOL allows that (I am sure some other languages do as well). Java inherited most of it's syntax from C which doesn't allow it.
You are human, and therefore you understand what the term "10 < x < 20" suppose to mean.
The computer doesn't have this intuition, so it reads it as:
"(10 < x) < 20".
For example, if x = 15, it will calculate:
(10 < x) => TRUE
"TRUE < 20" => ???
In C programming, it will be worse, since there are no True\False values.
If x = 5, the calculation will be:
10 < x => 0 (the value of False)
0 < 20 => non-0 number (True)
and therefore "10 < 5 < 20" will return True! :S
simplifying:
a = 10; b = 15; c = 20
public static boolean check(int a, int b, int c) {
return a<=b && b<=c;
}
This checks if b is between a and c
Because the < operator (and most others) are binary operators (they take two arguments), and (true true) is not a valid boolean expression.
The Java language designers could have designed the language to allow syntax like the type you prefer, but (I'm guessing) they decided that it was not worth the more complex parsing rules.
One can use Range class from the Guava library:
Range.open(10, 20).contains(n)
Apache Commons Lang has a similar class as well.
if (10 < x || x < 20)
This statement will evaluate true for numbers between 10 and 20.
This is a rough equivalent to 10 < x < 20

What is the result of i == (i = 2)?

Run the following code:
// In Java, output #####
public static void main(String[] args) {
int i = 1;
if(i == (i = 2)) {
System.out.println("#####");
} else {
System.out.println("#####");
}
}
But:
// In C, output #####,I did test on Clion(GCC 7.3) and Visual Studio 2017
int main(int argc, char *argv[]) {
int i = 1;
if(i == (i = 2)) {
printf("#####");
} else {
printf("#####");
}
return 0;
}
The motivation for asking this question comes from the following code:
// The code is from the JDK 11 - java.util.concurrent.atomic.AtomicInteger
// I am curious about the behavior of the variable prev.
public final int getAndUpdate(IntUnaryOperator updateFunction) {
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext)
next = updateFunction.applyAsInt(prev);
if (weakCompareAndSetVolatile(prev, next))
return prev;
haveNext = (prev == (prev = get()));
}
}
So, how to explain the above two different execution modes?
The behaviour of a C program that executes the expression i == (i = 2) is undefined.
It comes from C11 6.5p22:
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.84)
The i on the left-hand side of == is a value computation on the value of scalar object i and the right-hand side i = 2 has a side effect of assigning the value 2 to i. The LHS and RHS of == are unsequenced w.r.t. each other. Hence the entire program is meaningless in C.
Compile with gcc -Wall and GCC will spit out:
unsequenced.c:5:16: warning: operation on ‘i’ may be undefined [-Wsequence-point]
if(i == (i = 2)) {
~~~^~~~
Unlike C, Java guarantees the evaluation order for operands (left-to-right), therefore
haveNext = (prev == (prev = get()));
is correct in Java. The value of LHS is determined strictly before the evaluation of the side effect on the RHS occurs.
In C you have to write this as something like
newPrev = get();
haveNext = (prev == newPrev);
prev = newPrev;
The Java Language Specification (§15.7) states:
The Java programming language guarantees that the operands of operators appear
to be evaluated in a specific evaluation order, namely, from left to right.
The specification (§15.21.1) also states that:
The value produced by the == operator is true if the value of the left-hand
operand is equal to the value of the right-hand operand; otherwise, the result is
false.
Therefore in Java, the if-statement at runtime would look like the following, which obviously evaluates to false:
if (1 == 2) {
}
In C, it is simply undefined (see Antti's answer).
In C, the behavior of i == (i = 2) is undefined because it attempts to both update an object and use that object’s value in a computation without an intervening sequence point. The result will vary based on the compiler, compiler settings, even the surrounding code.

Bitwise operation in java or c

I would like to drastically improve the time performance of an operation I would best describe as a bit wise operation.
The following is a constructor for a BitFile class, taking three BitFile as parameters. Whichever bit the first and second parameter (firstContender and secondContender) agree on is taken from firstContender into the BitFile being constructed. Whichever bit they don't agree on is taken from the supportContender.
data is the class-field storing the result and the backbone of the BitFile class.
compare(byte,byte) returns true if both bytes are identical in value.
add(byte,int) takes a byte representing a bit and the index within the bit to extract, a second class-field "index" is used and incremented in add(byte,int) to put the next bit in location.
'BitFile.get(int)' returns a byte with just a specific bit being one, if it is one, BitFile.get(9) would return a byte with value 2 if the second bit of the second byte is a one, otherwise 0.
Xor bit wise operation can quickly tell me which bits are different in the two BitFile. Is there any quick way to use the result of a Xor, where all it's zeroes are represented by the firstContender's equivalent bit and all the one's are represented by the supportContender's equivalent bit, something like a
three operand Bit Wise operator?
public BitFile(
BitFile firstContender,BitFile secondContender,BitFile supportContender)
{
if(firstContender.getLength() != secondContender.getLength())
{
throw new IllegalArgumentException(
"Error.\n"+
"In BitFile constructor.\n"+
"Two BitFiles must have identical lengths.");
}
BitFile randomSet = supportContender;
int length = firstContender.getLength();
data = new byte[length];
for(int i = 0; i < length*8;i++)
{
if(compare(firstContender.get(i),secondContender.get(i)))
{
add(firstContender.get(i),i%8);
}
else
{
add(randomSet.get(i),i%8);
}
}
}
I found this question fairly confusing, but I think what you're computing is like this:
merge(first, second, support) = if first == second then first else support
So just choose where the bit comes from depending on whether the first and second sources agree or not.
something like a three operand Bit Wise operator?
indeed something like that. But of course we need to implement it manually in terms of operations supported by Java. There are two common patterns in bitwise arithmetic to choose between two sources based on a third:
1) (a & ~m) | (b & m)
2) a ^ ((a ^ b) & m)
Which choose, for each bit, the bit from a where m is zero, and from b where m is one. Pattern 1 is easier to understand so I'll use it but it's simple to adapt the code to the second pattern.
As you predicted, the mask in this case will be first ^ second, so:
for (int i = 0; i < data.length; i++) {
int m = first.data[i] ^ second.data[i];
data[i] = (byte)((first.data[i] & ~m) | (support.data[i] & m));
}
The same thing could easily be done with an array of int or long which would need fewer operations to process the same amount of data.

Is following true in java?

Is following true in java:
In java if you use || then after getting first true condition it neglects the rest conditions. That is If you write if(a || b || c) in java and java finds a is true then it will not check for b and c, just go into the if case.
Yes this is called short circuiting, if you put less expensive checks to the left you might avoid the expensive ones to follow.
This works for || and &&
one of the best uses is checking a value from an object that might be null:
if(myList != null && myList.size() > 6)
the previous line is null safe, reversing the condition will cause a null pointer exception in case myList is null
This is correct. || is called short-circuit OR evaluation, or an OR-ELSE operator.
This is important in situations when evaluating the right-hand side may cause an undesirable consequence:
if (myString == null || myString.indexOf("hello") != -1)
...
would crash if it were not for short-circuiting.
Yes, This way the compiler avoids unnecessary checking and calculation overhead.
That's correct, and that's not just laziness on part of the language implementation, but rather it is a crucial feature - short-circuiting allows you to write something like this:
if (myarray.length > 10 && myarray[10] == 5) { /* ... */ }
Here the second condition may only even be evaluated if the first one is true. Thanks to short-circuiting, if the first condition is false the second is never touched.
YES
(AFAIK)
The same things applies to && but in reverse manner.(for first false).
The same rule as in circuits for AND and OR gates.
Yes, it's called short-circuiting. It also will short circuit &&, i.e.
if (a && b && c)
If a is false then the condition cannot be true, neither b nor c are checked.
This can be problematic if you call methods that return booleans. To get around this, you can use bitwise & and |.
Yes it is correct. If you use | this operator to check OR condition then it checks rest all conditions. It also applied on AND(&) operator.
Yes, and one important thing, if you do any operations in the second part, they will not be made. For example:
int a = 5;
int b = 5;
if ( a == b || a++ == b){
...
}
//a = 5
//b = 5
BUT in case:
int a = 3;
int b = 5;
if ( a == b || a++ == b){
...
}
//a = 4
//b = 5
I tried to make a simple example, but sometimes you call a method in the second part, (which will not be called if first part was true in case of ||), or the first part was false in case of &&

& vs && -- how can the first case be used?

(a > b) & (c < d), the components are evaluated left to right, so (a >
b) is evaluated first. If (a > b) is false, the entire expression is
false regardless of the result of the component (r < d). Nevertheless,
the component (c < d) will still be evaluated. However, in the
expression (a > b) && (c < d), the component (c < d) will not be
evaluated if (a > b) evaluates to false. This is known as short
circuiting.
Came across this paragraph in a Java book. I have been programming in various languages before, but I've never found a need for '&'. Why would one want to evaluate the second statement if it's known that the end result is not affected by it? Is there any use for it; does it come due to historical reasons?
Same question applies to | and || as well.
The && operator is defined by the Java Language Specification to perform short-circuit evaluation.
However, the & operator is not, even when applied to boolean arguments.
You could exploit this if one of the arguments had side-effects that you did not want short-circuited. However, in my experience this is uncommon, and you'd face the risk of someone "fixing" it. It would be better separated into steps. For example, instead of:
if ( foo() & bar() ) {... }
you could say:
boolean isFoo = foo();
boolean isBar = bar();
if ( isFoo && isBar ) { ... }
if you expect your code to be under attack from timing attacks you want the least amount of branches (conditional execution paths) possible, this is one way to eliminate them
The difference between '&' and '&&' is not well-known and that example from the book doesn't help much.
Here's another example to show how short-circuiting work (using horrible methods having side-effects, but that's not the point).
Imagine you have this:
private int cnt;
private boolean a() {
cnt++;
return false;
}
private boolean b() {
cnt++;
return false;
}
If you execute the following:
cnt = 0;
if ( a() && b() ) {}
System.out.println( cnt );
It shall print 1.
While if you execute the following:
cnt = 0;
if ( a() & b() ) {}
System.out.println( cnt );
It shall print 2. Because in the latter case b() must be evaluated as per the language specs while in the first case b() must not be evaluated, as per the language specs.
You can use & in situations where you have to evaluate both subexpressions. For example, if they both have side effects that are observable by the rest of your application.
Perhaps the 2nd evaluation is in the form of an assignment statement or method call, in which case you might want it to execute. I wouldn't use bitwise operators in place of logical operators like this tho. If you need something to execute passed &&, then do it prior to your logical statement and store the result in a variable.
if(0 != ((a > b) ? 1 : 0) & ((c < d) ? 1 : 0)) {
// but really... (a > b) && (c < d), assuming no side-effects
}
...just use the logical operators (&& and ||) for conditions ;-) That is what they were designed for. If non-shortcircuit behavior is required, then restructure the code accordingly.
I think I have seen one case that had a somewhat valid use of & in this context, but I do not recall what it was so I mustn't have found it that valid ;-) In languages like C/C++ where there is no discreet "boolean" type, the (input) and result of & can be treated such that 0 -> false and non-0 -> true. As can be seen, however, Java has to jump through some fun to get bool -> int -> bool.
The only justification for a bit-wise operator is, well, bit-wise operations, IMOHO. Bit-wise operators are most useful when performing some sort of encoding including "bit fields" and "bit masks". They are also useful when dealing with fun arising from Java's signed-only bytes, etc.
I think the bigger (only?) point to take away is that && and || are short-circuiting -- they are actually the only operators with this behavior (arguments over ?: excluded); the rest is just to explain the eager-behavior of bit-wise operators. This just goes to re-enforce the rule: do not cause side-effects in conditionals (outside of a few well-accepted idioms, but even then, keep it simple).
Happy coding.
Examples of bit-wise usage:
Imagine the use of flags which are stored into a single "integer" slot in a serialized format:
int flags = 0;
if (this.encypted) {
flags |= EncryptedMode;
}
out.write(flags);
// later on
int flags = in.readInt();
this.encrypted = (flags & EncryptedMode) != 0;
Reading the "unsigned value" of a byte:
byte[] data = {-42, ...}; // read in from file or something
int unsignedByte = data[0] & 0xFF;
Your book is confusing things. For the most part, you will only use '&&' and '||'. The single ones, '&' and '|', are bitwise operators - you can read more about them here: http://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
The use of a non-short-circuit operator may speed up performance-critical code by avoiding branch mis-prediction stalls, which could easily amount to a dozen or more clock cycles.

Categories