Was bedeutet "| ="? (Pipe Equal Operator)

249

Ich habe versucht, mit der Google-Suche und dem Stapelüberlauf zu suchen, aber es wurden keine Ergebnisse angezeigt. Ich habe dies im OpenSource-Bibliothekscode gesehen:

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

Was bedeutet "| =" ( pipe equal operator)?

wtsang02
quelle
4
Ich frage mich, ob das Hinzufügen von etwas pipe equal operatorzu dieser Frage oder einer anderen Dokumentation zu diesem Thema den Leuten bei der Suche nicht helfen würde.
Denys Séguret
10
@EJP sind ihr sprechen darüber docs . Es wird deutlich, dass in den Dokumenten keine Dokumentation zur Verwendung vorhanden ist .
wtsang02
36
Wenn Sie nicht wissen, dass es Pipe Equal heißt, ist es wirklich schwierig zu suchen, ohne jemanden zu fragen.
Ataulm
@ataulm verbrachte tatsächlich einige Zeit damit, herum zu googeln, um einen Begriff zu finden, vertical barder mich schließlich hierher führte.
Ruuter
1
Mögliches Duplikat von Was macht der Operator | = in Java?
Poring91

Antworten:

323

|=liest sich genauso wie +=.

notification.defaults |= Notification.DEFAULT_SOUND;

ist das gleiche wie

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

Wo |ist der bitweise ODER-Operator?

Alle Operatoren werden hier referenziert .

Ein bitweiser Operator wird verwendet, da diese Konstanten, wie häufig, es einem int ermöglichen, Flags zu tragen.

Wenn Sie sich diese Konstanten ansehen , werden Sie feststellen, dass sie Zweierpotenzen haben:

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

Sie können also bitweises ODER verwenden, um Flags hinzuzufügen

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

so

myFlags |= DEFAULT_LIGHTS;

bedeutet einfach, dass wir eine Flagge hinzufügen.

Und symmetrisch testen wir, ob ein Flag gesetzt ist mit &:

boolean hasVibrate = (DEFAULT_VIBRATE & myFlags) != 0;
Denys Séguret
quelle
2
Genau wie j += 1;ist das gleiche wie j = j + 1;.
David Schwartz
1
@ARS: Ich kann nicht denken Sie an ein Gegenbeispiel in Java (vielleicht , wenn jist volatile?), Aber ich werde dafür Wort nehmen.
David Schwartz
6
@ DavidSchwartz Siehe dies
Arshajii
2
boolean hasVibrate = DEFAULT_VIBRATE & myFlags;- können Sie von übersetzen intzu booleanwie in Java? Das wäre in C gültig, aber ich dachte, in Java boolean hasVibrate = ((DEFAULT_VIBRATE & myFlags) == DEFAULT_VIBRATE);
müsste
1
@ DavidSchwartz Wow, dieser Vergleich mit +=hat mir endlich geholfen, es zu verstehen. Vielen Dank!
C4d
39

Sie haben bereits eine ausreichende Antwort auf Ihre Frage. Aber vielleicht hilft Ihnen meine Antwort mehr über die |=Art der binären Operatoren.

Ich schreibe eine Tabelle für bitweise Operatoren :
Folgendes ist gültig:

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

Beachten Sie, dass alle Operatoren binäre Operatoren sind.

Auch Anmerkung: (für unten Punkte Ich wollte meine Antwort hinzufügen)

  • >>>ist ein bitweiser Operator in Java, der als vorzeichenlose Verschiebung bezeichnet wird
    aber >>>=kein Operator in Java. >>> = Operator

  • ~ist bitweise Komplementbits 0 to 1 and 1 to 0(unärer Operator), aber ~=kein Operator.

  • Zusätzlich als !logischer NICHT-Operator bezeichnet, !=prüft jedoch, ob der Wert von zwei Operanden gleich ist oder nicht. Wenn die Werte nicht gleich sind, wird die Bedingung wahr. zB (A != B) is true. wobei als A=!BMittel , wenn Bist , truedann Awerden false(und wenn Bist , falsedann Awerden true).

Randnotiz: |heißt nicht Pipe, sondern heißt OR, Pipe ist Shell-Terminologie. Übertragen Sie einen Prozess zum nächsten.

Grijesh Chauhan
quelle
9
Ich hatte den Eindruck, dass "Pipe" der Name des Charakters war, von dem der Shell-Begriff stammt. In Wikipedia wird es jedoch als "vertikaler Balken" bezeichnet, und "Pipe" ist spezifisch für Shell-Befehle. Ich wollte mich nur für das Hinzufügen dieser Randnotiz bedanken!
Caleb Brinkman
18

Ich suchte nach einer Antwort auf das, was |=in Groovy funktioniert, und obwohl die obigen Antworten richtig sind, haben sie mir nicht geholfen, einen bestimmten Code zu verstehen, den ich mir angesehen habe.

Insbesondere wenn es auf eine boolesche Variable angewendet wird, setzt "| =" sie auf TRUE, wenn sie zum ersten Mal auf einen wahrheitsgemäßen Ausdruck auf der rechten Seite trifft, und hält ihren TRUE-Wert für alle nachfolgenden Aufrufe | =. Wie ein Riegel.

Hier ein vereinfachtes Beispiel dafür:

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 

Ausgabe:

false
false
true
true

Edit : Warum ist das nützlich?

Stellen Sie sich eine Situation vor, in der Sie wissen möchten, ob sich an einer Vielzahl von Objekten etwas geändert hat, und benachrichtigen Sie in diesem Fall eine der Änderungen. Sie würden also einen hasChangesBooleschen Wert einrichten und ihn auf |= diff (a,b)und dann |= dif(b,c)usw. setzen. Hier ein kurzes Beispiel:

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
quelle
10
Ja, das gilt auch für Java. Aber es erwähnenswert, dass solche ODER - Operation y|=exprist nicht kurzgeschlossen werden ( im Gegensatz zu y = y || expr), was bedeutet , dass exprimmer ausgewertet. Das war nicht offensichtlich für mich zum ersten Mal :) So ist es wichtig zu beachten ist , vor , dass der Ersatz Refactoring y|=expry=y||xist nicht semantisch äquivalent , falls exprNebenwirkungen tatsächlich hat.
NIA
1
Und diesen Geist in mit, in Ihrem Fall mit , hasChangeses wäre wahrscheinlich besser, liebe y=y||xForm profitiert von Kurz ciruit, denn wenn Sie eine Veränderung gefunden wird es nicht wirklich susequent diffs tun muß , weil Sie bereits die Antwort wissen. (Besonders wichtig in der realen Lebenssituation, wenn verglichene Objekte kompliziert sind und diffes nicht ganz schnell geht)
NIA
@NIA Danke für die Abstimmung. Ja, ich stimme Ihrem Standpunkt zum Kurzschluss zu.
Dbrin
2
@FranklinYu natürlich keine Implementierungsdetails. Nicht-Kurzschluss wird an der Stelle, auf die Sie verwiesen haben, nicht speziell erwähnt, nur weil es nicht die Besonderheit ist - es ist das Standard- und Normalverhalten für die meisten Bediener. Die Besonderheit ist tatsächlich der Kurzschluss von ||und &&, und in den entsprechenden Abschnitten 15.23 und 15.24 der Spezifikation wird diese Tatsache klar erklärt und dieser Unterschied zu |und &hervorgehoben.
NIA
2
@FranklinYu Ich denke, es war nicht nötig, weiter unten in dem Abschnitt, auf den Sie verwiesen haben (15.26.2 "Compund-Zuweisungsoperatoren"), noch einmal etwas dazu zu sagen, nur weil Compond-Zuweisungen einfach immer nicht kurzgeschlossen sind (es gibt keine ||=und &&=Operatoren, die dies tun würden gegen die Regel verstoßen und besondere Erwähnung erfordern).
NIA
13

Es ist eine Verkürzung dafür:

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

Und |ist ein bisschen weise ODER.

Bis Helge
quelle
3

Hinweis: || = existiert nicht. (logisch oder) Sie können verwenden

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

oder

y = expr ? true : y;  // expr is always evaluated.
woens
quelle
4
Nicht ganz vollständig: Sie können immer noch y |= exprmit Booleschen Werten arbeiten und es gibt das gleiche Ergebnis ywie bei Ihren Varianten mit dem wichtigen Hinweis, dass es kein Kurzschluss ist , was bedeutet, dass Ausdruck immer ausgewertet wird, auch im Fall vony==true
NIA