问题
I just going through code someone has written and I saw |=
usage, looking up on Java operators, it suggests bitwise or and assign operation, can anyone explain and give me an example of it?
Here is the code that read it:
for (String search : textSearch.getValue())
matches |= field.contains(search);
回答1:
a |= b;
is the same as
a = (a | b);
It calculates the bitwise OR of the two operands, and assigns the result to the left operand.
To explain your example code:
for (String search : textSearch.getValue())
matches |= field.contains(search);
I presume matches
is a boolean
; this means that the bitwise operators behave the same as logical operators.
On each iteration of the loop, it OR
s the current value of matches
with whatever is returned from field.contains()
. This has the effect of setting it to true
if it was already true, or if field.contains()
returns true.
So, it calculates if any of the calls to field.contains()
, throughout the entire loop, has returned true
.
回答2:
a |= b
is the same as a = (a | b)
Boolean Variables
In a boolean
context, it means:
if (b) {
a = true;
}
that is, if b
is true then a
will be true, otherwise a
will be unmodified.
Bitwise Operations
In a bit wise context it means that every binary bit that's set in b
will become set in a
. Bits that are clear in b
will be unmodified in a
.
So if bit 0 is set in b
, it'll also become set in a
, per the example below:
This will set the bottom bit of an integer:
a |= 0x01
This will clear the bottom bit:
a &= ~0x01
This will toggle the bottom bit:
a ^= 0x01;
回答3:
This code:
int i = 5;
i |= 10;
is equivalent to this code:
int i = 5;
i = i | 10;
Similarly, this code:
boolean b = false;
b |= true;
is equivalent to this one:
boolean b = false;
b = b | true;
In the first example, a bit-wise OR is being performed. In the second example, a boolean OR is performed.
回答4:
Could it be possible that the code has a bug and it was meant
matches = matches || field.contains(search);
so that matches should be true
if at least one field contains the search
variable?
回答5:
a |= b
is the same as a = a | b
a | b
is a bitwise operator if both operands are integral types (int, short, etc...). If both operands are booleans, then its is a boolean or.
When both a
and b
are booleans, the difference between a | b
and a || b
is that in the first, both sides are always evaluated, in the later b
is only evaluated if a
is false. It is sort of a "shortcut" operator.
This is useful for situations like this:
if (a == null || a.equals(b)) { .. do something .. } // works
if (a == null | a.equals(b)) { .. do something .. } // NPE if a is null
On the other hand, ||
actually is implemented as another conditional jump in the bytecode/machine-code. In some cases, it may be faster to evaluate boolean conditions using the |
operator to avoid the additional jump (and thus branch predition, etc...). Definitely something for low-level micro-benchmarking to figure out which is better (and usually not important in most applications).
When you do a |= b
you are always evaluating both a
and b
. It doesn't really make sense to have an a ||= b
operators, since the equivalent a = a || b
would translate to:
if (a) a = true;
else if (b) a = true
else a = false;
...due to the conditional nature of ||
evaluation. In other words, b
would not be evaluated if a
was already true.
回答6:
That code snippet is a poor example of when to use that operator. Honestly I can't think of a great example of when to use this operator, but here's my best attempt:
boolean somethingIsTrue = testSomethingTrue();
if(somethingIsTrue){
//Do something
}
somethingIsTrue |= testSomethingElseTrue();
if(somethingIsTrue){
//Do something else
}
somethingIsTrue |= testSomethingElseTrue2();
if(somethingIsTrue){
//Do something else than something or something else
}
Note: You need 3 ifs because otherwise you could just do somethingIsTrue | testSomethingElseTrue()
for the second if.
In case you were wondering why you shouldn't use the operator in the first example, here's why:
From a performance standpoint, it is poor because it does a compare and an assign for each loop instead of just a compare. Also, it continues iterating even when future iterations will have no effect (once matches
gets set to true
it will not change, and String.contains
has no side effects).
It is also poor from a readability standpoint, based solely on the existence of this question ;)
Thus, in place of that snippet I'd go for:
for (String search : textSearch.getValue()){
if(field.contains(search)){
matches = true;
break;
}
}
On a side note, it seems to me like the original coder might have been playing a bit too much code-golf when (s)he wrote this :)
来源:https://stackoverflow.com/questions/10142059/java-operators-bitwise-or-and-assign-example