23

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);
4
  • Could you show us the code you read? Commented Apr 13, 2012 at 13:49
  • @talnicolas: updated question with code . Commented Apr 13, 2012 at 13:50
  • What is the type of matches? int or boolean? Commented Apr 13, 2012 at 13:51
  • see my answer, probably bitwise-or is not meant at all here! Commented Apr 13, 2012 at 13:56

6 Answers 6

32
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 ORs 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.

Sign up to request clarification or add additional context in comments.

4 Comments

can you put in some values for a and b?
oh ok, now it make some sense
"this means that the bitwise operators behave the same as logical operators". Actually, logical operators will short-circuit. Short circuiting is probably desired here.
It should also be noted that if contains() has no side-effects, this is rather inefficient. Adding at least an if (matches) { break; } inside the loop would be so much nicer... (Although I suppose getValue() may be returning so few searches that it won't make a noticeable difference...)
14

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;

1 Comment

can put in some number values for a and explain the detail ooperation.
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.

Comments

3

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.

Comments

1

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 Comments

your code is not functionally the same - if matches is already true then the short circuit operator will prevent evaluation of field.contains(search). AFAIK the |= operator won't do that.
Which means my code is optimization of the original code
only if it's truly intended that .contains() is not called in those circumstances.
you mean if the .contains() method does not have side-effects
yeah, mostly - in this case it probably doesn't matter, but it's worth knowing that for boolean variables a |= func() is the same as a = a | func() which is not functionally the same as a = a || func(), even though the end result on a is the same.
0

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 :)

1 Comment

There are many good use cases for this operator. Imagine methods like addAll or removeAll in a set, provided that you iterate over the collection in parameter. You add or remove in a loop, and you want to return true if you actually added or removed at least one entry.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.