「| =」はどういう意味ですか?(パイプ等価演算子)


249

Google検索とスタックオーバーフローを使用して検索を試みましたが、結果が表示されませんでした。私はこれをオープンソースのライブラリコードで見ました:

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

"| ="(pipe equal operator)はどういう意味ですか?


4
pipe equal operatorこの質問に何かを追加したり、トピックに関する他のドキュメントを追加しても、ユーザーが検索するのに役立ちませんか。
DenysSéguret2013年

10
@EJPは皆さん、このドキュメントについて話しています。これは、ドキュメントの使用に関するドキュメントがないことをドキュメントに明確に伝えます。
wtsang02 2013年

36
パイプイコールと呼ばれていることを知らない限り、誰かに尋ねずに検索するのは本当に難しいです。
ataulm 2013年

@ataulmは確かに、vertical bar私をここまで導いた用語を思いつくためにグーグルで少し時間を費やしました。
ruuter、

回答:


323

|=と同じように読みます+=

notification.defaults |= Notification.DEFAULT_SOUND;

と同じです

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

ここ|で、ビット単位のOR演算子です。

すべての演算子はここで参照されます

よくあることですが、これらの定数によりintがフラグを運ぶことができるため、ビット単位の演算子が使用されます。

あなたがいる場合に見えるこれらの定数で、あなたは彼らが2のべき乗にいることがわかります。

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

したがって、ビット単位のORを使用してフラグを追加できます

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

そう

myFlags |= DEFAULT_LIGHTS;

単にフラグを追加することを意味します。

対称的に、フラグを設定してテストし&ます:

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

2
と同じj += 1;ですと同じj = j + 1;です。
David Schwartz

1
@ARS:私はJavaでの反例(多分そうjですvolatileか?)を考えることはできませんが、私はあなたの言葉を採用します。
David Schwartz、

6
@DavidSchwartz See this
arshajii

2
boolean hasVibrate = DEFAULT_VIBRATE & myFlags;-Javaからintに変換できますbooleanか?これはCでは有効ですが、Javaではboolean hasVibrate = ((DEFAULT_VIBRATE & myFlags) == DEFAULT_VIBRATE);
BlueRaja-Danny Pflughoeft

1
@DavidSchwartzうわー、との比較+=は私にそれを理解するためのトリックをついにやった。ありがとう!
C4d

39

質問に対する回答はすでに十分です。しかし、私の答え|=は、二項演算子の種類についてあなたを助けるかもしれません。

私はビット演算子の表を書いています:
以下は有効です:

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

すべての演算子は二項演算子であることに注意してください。

また、注:( 以下のポイントについて、私の回答を追加したかった)

  • >>> 呼び出されるJavaのビット演算子 符号なしシフト
    しかし >>>=いないJavaでオペレータ。 >>> =演算子

  • ~ビット単位の補数ビットです0 to 1 and 1 to 0(単項演算子)。~=、演算子ではありません。

  • さらに、!論理NOT演算子と 呼ばれ!=ますが、2つのオペランドの値が等しいかどうかをチェックし、値が等しくない場合に条件がtrueになります。例えば(A != B) is true。ここで、A=!Bif BtruethenにAなるfalse(そしてif BfalsethenにAなるtrue)ことを意味します。

補足:|パイプとは呼ばれず、代わりにORと呼ばれます。パイプはシェルの用語であり、1つのプロセスを次のプロセスに転送します。


9
「パイプ」というのは、シェル用語の由来であるキャラクターの名前だという印象を受けました。しかし、ウィキペディアを見ると、これは実際には「垂直バー」と呼ばれ、「パイプ」はシェルコマンドに固有です。そのサイドノートを追加してくれてありがとう!
Caleb Brinkman、2014

18

私は|=Groovy で何ができるかについての回答を探していましたが、上記の回答は正しいのですが、私が見ている特定のコードを理解するのに役立ちませんでした。

特に、ブール変数「| =」に適用すると、右側で真の式に初めて遭遇したときにTRUEに設定され、以降のすべての呼び出しでそのTRUE値が保持されます。ラッチのようです。

これの簡単な例:

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 

出力:

false
false
true
true

編集:なぜこれが便利なのですか?

さまざまなオブジェクトで何かが変更されたかどうかを知りたい場合は、変更の一部を通知してください。したがって、hasChangesブール値を設定し|= diff (a,b)、それを次に設定し ます|= dif(b,c)。以下に簡単な例を示します。

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

10
はい、Javaでも同じことが言えます。ただし、そのようなOR演算y|=exprは(とは異なり)短絡でないy = y || exprこと、つまりexpr常に評価されることを意味します。これは私にとって初めて明らかではありませんでした:)したがって、リファクタリング前に、実際に副作用がある場合、置換y|=expry=y||x意味的に同等ではないことに注意することが重要exprです。
NIA 2017

1
そして、心の中でこれを持つ あなたのケースにしてhasChanges、それはでしょう、おそらく好む方が良いy=y||xあなたがどんな変更を見つけたとき、あなたはすでに答えを知っているので、実際にsusequent差分を行うために必要とされていないため、短期ciruitから利益のためにフォームを。(特に、比較対象のオブジェクトが複雑で実際の状況でdiffそれらを使用する場合、それほど高速ではない場合に特に重要です)
NIA

@NIA賛成票をありがとう。はい、短絡についてのあなたの意見に同意します。
dbrin 2017

2
@FranklinYuはもちろん実装の詳細ではありません。非短絡性は、特異性ではないという理由だけで、参照した場所で特に言及されていません。これは、ほとんどの演算子のデフォルトで通常の動作です。クセは実際の短期circutinessである||&&、対応するセクションで15.2315.24仕様のこの事実が明確に宣言され、この差から、|&強調しています。
NIA 2018

2
@FranklinYuだから私は再び、以下のセクションでは、あなたが参照このひとことする必要はありませんでしたと思います(15.26.2「Compund代入演算子」) compond割り当てがそこにはある(非短絡単に、常にではないという理由だけ||=とは&&=どのだろう演算子ルールに違反し、特別な言及が必要です)。
NIA 2018

13

これは短縮形です:

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

そして|、ビットごとのORです。



3

注:|| =は存在しません。(論理または)使用できます

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

または

y = expr ? true : y;  // expr is always evaluated.

4
完全ではない:y |= exprブール値でも使用できy、バリアントと同じ結果が得られます。これはshort-curtuitではないという重要な注意です。つまり、y==true
NIA
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.