357

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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
wtsang02
  • 18,603
  • 10
  • 49
  • 67
  • 5
    I wonder if adding something like `pipe equal operator` to this question or any other documentation on the topic wouldn't help people searching. – Denys Séguret Jan 13 '13 at 09:59
  • 11
    @EJP are you guys talking about this [docs](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html). It clearly tells the docs lacks documentation about the **use** of this. – wtsang02 Jan 16 '13 at 02:34
  • 55
    Unless you knew it was called pipe equal, it's really difficult to search for without asking someone. – ataulm May 03 '13 at 19:50
  • 2
    @ataulm indeed, spent some time googling around to come up with a term `vertical bar` which finally led me here. – ruuter Nov 21 '16 at 22:38
  • Possible duplicate of [what does |= (single pipe equal) and &=(single ampersand equal) mean](http://stackoverflow.com/questions/6942477/what-does-single-pipe-equal-and-single-ampersand-equal-mean) – phuclv Mar 03 '17 at 02:43
  • @LưuVĩnhPhúc I think they both provide different values to different users. They should co exist. If not, according to [http://meta.stackexchange.com/questions/10841/how-should-duplicate-questions-be-handled ](meta post) , the one with better collection of answers should stay. I would say there are generally better here. – wtsang02 Mar 07 '17 at 00:55
  • 1
    Possible duplicate of [What does the |= operator do in Java?](http://stackoverflow.com/questions/2325349/what-does-the-operator-do-in-java) – poring91 May 08 '17 at 03:00

6 Answers6

443

|= 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;
Pablo Rivas
  • 941
  • 9
  • 16
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
47

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

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • 15
    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! – Caleb Brinkman Jul 06 '14 at 04:51
30

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
dbrin
  • 15,525
  • 4
  • 56
  • 83
  • 19
    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|=expr` ↔ `y=y||x` is **not semantically equivalent** in case `expr` actually has side effects. – NIA Aug 30 '17 at 14:04
  • 2
    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 `diff`ing them them is not quite fast) – NIA Aug 30 '17 at 14:12
  • @NIA Thanks for the up vote. Yes I agree with your point about short circuiting. – dbrin Aug 31 '17 at 14:59
  • @NIA Thanks a lot! But this pitfall is not mentioned in [standard](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.26.2); is it implementation detail? – Franklin Yu Sep 09 '18 at 18:19
  • 2
    @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](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.23) and [15.24](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.24) of specification this fact is clearly declared, and this difference from `|` and `&` is emphasized. – NIA Sep 12 '18 at 17:34
  • 2
    @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). – NIA Sep 12 '18 at 17:36
16

It's a shortening for this:

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

And | is a bit-wise OR.

Till Helge
  • 9,253
  • 2
  • 40
  • 56
10

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

ford
  • 10,687
  • 3
  • 47
  • 54
5

Note: ||= does not exist. (logical or) You can use

y= y || expr; // expr is NOT evaluated if y==true

or

y = expr ? true : y;  // expr is always evaluated.
woens
  • 1,058
  • 9
  • 20
  • 11
    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 Aug 30 '17 at 13:54
  • simplified version: `y = expr || y; // expr is always evaluated.` – Dmytro Dec 28 '21 at 21:34