What does "|=" mean? (pipe equal operator)

268,922

Solution 1

|= reads the same way as +=.

notification.defaults |= Notification.DEFAULT_SOUND;

is the same as

notification.defaults = notification.defaults | Notification.DEFAULT_SOUND;

where | is the bit-wise OR operator.

All operators are referenced here.

A bit-wise operator is used because, as is frequent, those constants enable an int to carry flags.

If you look at those constants, you'll see that they're in powers of two :

public static final int DEFAULT_SOUND = 1;
public static final int DEFAULT_VIBRATE = 2; // is the same than 1<<1 or 10 in binary
public static final int DEFAULT_LIGHTS = 4; // is the same than 1<<2 or 100 in binary

So you can use bit-wise OR to add flags

int myFlags = DEFAULT_SOUND | DEFAULT_VIBRATE; // same as 001 | 010, producing 011

so

myFlags |= DEFAULT_LIGHTS;

simply means we add a flag.

And symmetrically, we test a flag is set using & :

boolean hasVibrate = (DEFAULT_VIBRATE & myFlags) != 0;

Solution 2

You have already got sufficient answer for your question. But may be my answer help you more about |= kind of binary operators.

I am writing table for bitwise operators:
Following are valid:

----------------------------------------------------------------------------------------
Operator   Description                                   Example
----------------------------------------------------------------------------------------
|=        bitwise inclusive OR and assignment operator   C |= 2 is same as C = C | 2
^=        bitwise exclusive OR and assignment operator   C ^= 2 is same as C = C ^ 2
&=        Bitwise AND assignment operator                C &= 2 is same as C = C & 2
<<=       Left shift AND assignment operator             C <<= 2 is same as C = C << 2
>>=       Right shift AND assignment operator            C >>= 2 is same as C = C >> 2  
----------------------------------------------------------------------------------------

note all operators are binary operators.

Also Note: (for below points I wanted to add my answer)

  • >>> is bitwise operator in Java that is called Unsigned shift
    but >>>= not an operator in Java. >>>= operator

  • ~ is bitwise complement bits, 0 to 1 and 1 to 0 (Unary operator) but ~= not an operator.

  • Additionally, ! Called Logical NOT Operator, but != Checks if the value of two operands are equal or not, if values are not equal then condition becomes true. e.g. (A != B) is true. where as A=!B means if B is true then A become false (and if B is false then A become true).

side note: | is not called pipe, instead its called OR, pipe is shell terminology transfer one process out to next..

Solution 3

I was looking for an answer on what |= does in Groovy and although answers above are right on they did not help me understand a particular piece of code I was looking at.

In particular, when applied to a boolean variable "|=" will set it to TRUE the first time it encounters a truthy expression on the right side and will HOLD its TRUE value for all |= subsequent calls. Like a latch.

Here a simplified example of this:

groovy> boolean result  
groovy> //------------ 
groovy> println result           //<-- False by default
groovy> println result |= false 
groovy> println result |= true   //<-- set to True and latched on to it
groovy> println result |= false 

Output:

false
false
true
true

Edit: Why is this useful?

Consider a situation where you want to know if anything has changed on a variety of objects and if so notify some one of the changes. So, you would setup a hasChanges boolean and set it to |= diff (a,b) and then |= dif(b,c) etc. Here is a brief example:

groovy> boolean hasChanges, a, b, c, d 
groovy> diff = {x,y -> x!=y}  
groovy> hasChanges |= diff(a,b) 
groovy> hasChanges |= diff(b,c) 
groovy> hasChanges |= diff(true,false) 
groovy> hasChanges |= diff(c,d) 
groovy> hasChanges 

Result: true

Solution 4

It's a shortening for this:

notification.defaults = notification.defaults | Notification.DEFAULT_SOUND;

And | is a bit-wise OR.

Solution 5

| is the bitwise-or operator, and it is being applied like +=.

Share:
268,922
wtsang02
Author by

wtsang02

College student at NYIT , seeking for knowledge, excitement in the Computer Science field.

Updated on February 17, 2020

Comments

  • wtsang02
    wtsang02 about 4 years

    I tried searching using Google Search and Stack Overflow, but it didn't show up any results. I have seen this in opensource library code:

    Notification notification = new Notification(icon, tickerText, when);
    notification.defaults |= Notification.DEFAULT_SOUND;
    notification.defaults |= Notification.DEFAULT_VIBRATE;
    

    What does "|=" ( pipe equal operator ) mean?

    • Denys Séguret
      Denys Séguret over 11 years
      I wonder if adding something like pipe equal operator to this question or any other documentation on the topic wouldn't help people searching.
    • wtsang02
      wtsang02 over 11 years
      @EJP are you guys talking about this docs. It clearly tells the docs lacks documentation about the use of this.
    • ataulm
      ataulm almost 11 years
      Unless you knew it was called pipe equal, it's really difficult to search for without asking someone.
    • ruuter
      ruuter over 7 years
      @ataulm indeed, spent some time googling around to come up with a term vertical bar which finally led me here.
    • phuclv
      phuclv about 7 years
    • wtsang02
      wtsang02 about 7 years
      @LưuVĩnhPhúc I think they both provide different values to different users. They should co exist. If not, according to [meta.stackexchange.com/questions/10841/… ](meta post) , the one with better collection of answers should stay. I would say there are generally better here.
    • poring91
      poring91 almost 7 years
  • David Schwartz
    David Schwartz over 11 years
    Just like j += 1; is the same as j = j + 1;.
  • Jason Sperske
    Jason Sperske over 11 years
    In Java 7> int defaults = 0b1001; defaults |= 0b1010; defaults == 0b1011;
  • arshajii
    arshajii over 11 years
    @DavidSchwartz Although j += 1 isn't exactly the same as j = j + 1.
  • David Schwartz
    David Schwartz over 11 years
    @A.R.S.: I can't think of a counter-example in Java (maybe if j is volatile?), but I'll take your word for it.
  • arshajii
    arshajii over 11 years
    @DavidSchwartz See this
  • BlueRaja - Danny Pflughoeft
    BlueRaja - Danny Pflughoeft over 11 years
    boolean hasVibrate = DEFAULT_VIBRATE & myFlags; - can you translate from int to boolean like that in Java? That would be valid in C, but I thought in Java it had to be written as boolean hasVibrate = ((DEFAULT_VIBRATE & myFlags) == DEFAULT_VIBRATE);
  • Denys Séguret
    Denys Séguret over 11 years
    @BlueRaja-DannyPflughoeft You're right. I edited to fix that line.
  • Caleb Brinkman
    Caleb Brinkman almost 10 years
    I was under the impression that "pipe" was the name of the character, which is where the shell term came from. But, looking at Wikipedia, it's actually called a "vertical bar" and "pipe" is specific to shell commands. Just wanted to say thanks for adding that side note!
  • Everett
    Everett over 7 years
    Thank you for answering the question instead of doing like everyone else, which is to recommend that the author read the entire Java Language Specification to figure out what this means
  • C4d
    C4d over 7 years
    @DavidSchwartz Wow, that comparison with += finally did the trick for me understanding it. Thanks!
  • NIA
    NIA over 6 years
    Not quite complete: you still can use y |= expr with booleans and it gives the same result on y as your variants with the important note that it is not short-curtuit, meaning that expr is always evaluated, even in case of y==true
  • NIA
    NIA over 6 years
    Yep, the same holds in Java. But it worth noting that such OR operation y|=expr is not short-circuit (unlike y = y || expr), meaning that expr always evaluated. This was not obvious for me for the first time :) So it is important to note before refactoring that replacement y|=expry=y||x is not semantically equivalent in case expr actually has side effects.
  • NIA
    NIA over 6 years
    And, having this in mind, in your case with hasChanges it would probably be better to prefer y=y||x form to benefit from short-ciruit, because when you found any change it is not actually needed to do susequent diffs because you already know the answer. (Especially important in real life situation when compared objects are complicated and diffing them them is not quite fast)
  • dbrin
    dbrin over 6 years
    @NIA Thanks for the up vote. Yes I agree with your point about short circuiting.
  • Franklin Yu
    Franklin Yu over 5 years
    @NIA Thanks a lot! But this pitfall is not mentioned in standard; is it implementation detail?
  • NIA
    NIA over 5 years
    @FranklinYu of course not implementation detail. Non-short-circuitness is not specifically mentioned at the place you referenced just because it is not the peculiarity - it is the default and normal behavior for most of operators. The peculiarity is actually the short-circutiness of || and &&, and in corresponding sections 15.23 and 15.24 of specification this fact is clearly declared, and this difference from | and & is emphasized.
  • NIA
    NIA over 5 years
    @FranklinYu So I think there was no need to say something about this again below in section you referenced (15.26.2 "Compund assignment operators") just because compond assignments are simply always non-short-circuit (there are no ||= and &&= operators which would break the rule and require special mentioning).
  • Dmytro
    Dmytro over 2 years
    simplified version: y = expr || y; // expr is always evaluated.