Warum verwenden wir normalerweise ||? über |? Was ist der Unterschied?

219

Ich frage mich nur, warum wir normalerweise ein logisches ODER ||zwischen zwei Booleschen Werten verwenden, die nicht bitweise ODER sind |, obwohl beide gut funktionieren.

Ich meine, schauen Sie sich Folgendes an:

if(true  | true)  // pass
if(true  | false) // pass
if(false | true)  // pass
if(false | false) // no pass
if(true  || true)  // pass
if(true  || false) // pass
if(false || true)  // pass
if(false || false) // no pass

Können wir |statt verwenden ||? Gleiches mit &und &&.

Eng.Fouad
quelle
16
Die meisten Leute vergessen das ist ein nicht kurzschließender boolescher Operator und ein bitweiser Operator.
John Meagher
1
Details zum Unterschied finden Sie im JLS. Siehe java.sun.com/docs/books/jls/third_edition/html/…
John Meagher
64
Sie sind nicht gleich. Bitte lesen Sie die dazugehörigen Tutorials, insbesondere zur Kurzschlussbewertung im Vergleich zur eifrigen Bewertung . ||und &&kurzschließen während |und &sind eifrig.
Luftkissenfahrzeug voller Aale
4
In welchem ​​Fall möchten Sie aus Neugier die nicht kurzgeschlossenen Versionen verwenden? Ich sehe fast immer &&und ||, aber nie & |. Wenn Sie etwas tun, das von Nebenwirkungen abhängt, verstehe ich nicht, warum Sie so etwas verwenden würden, (a & b | c)da jemand leicht denken könnte: "Ich kann dies durch die Verwendung der kurzgeschlossenen Versionen optimieren."
Mike Bailey
2
Und natürlich haben sie unterschiedliche Vorrang.
Hot Licks

Antworten:

349

Wenn Sie die ||und &&-Formen anstelle der |und &-Formen dieser Operatoren verwenden, wird Java nicht die Mühe machen, den rechten Operanden allein auszuwerten.

Es ist eine Frage, ob Sie die Auswertung kurzschließen möchten oder nicht - meistens möchten Sie.

Ein guter Weg, um die Vorteile eines Kurzschlusses zu veranschaulichen, wäre das folgende Beispiel.

Boolean b = true;
if(b || foo.timeConsumingCall())
{
   //we entered without calling timeConsumingCall()
}

Ein weiterer Vorteil des Kurzschlusses ist, wie Jeremy und Peter erwähnt haben, die Nullreferenzprüfung:

if(string != null && string.isEmpty())
{
    //we check for string being null before calling isEmpty()
}

Mehr Info

Shawn
quelle
115
Das kanonische Beispiel istfoo != null && foo.hasBar()
Jeremy
1
Wenn Sie mit | eine mögliche Nullreferenzausnahme hinzufügen von @ Jeremys Kommentar dann ist dies eine großartige Antwort.
Peter Kelly
Denken Sie auch daran, dass && und || bedeutet eine Verzweigungsanweisung auf Maschinencodeebene (denken Sie daran, dass Verzweigungen zu Fehlvorhersagen für Verzweigungen führen können). Wenn Sie also über die Leistung sehr pedantisch sind, verwenden Sie sie nur, wenn sie tatsächlich benötigt werden ( foo != null && foo.hasBar()) oder schneller ( b || foo.timeConsumingCall()). 99% der Entwickler sollten sich jedoch keine Gedanken über diese Mikrooptimierung machen müssen.
Jonathan Dickinson
3
Ich bin überrascht, dass niemand erwähnt hat, wann Sie | verwenden möchten. Das häufigste Szenario, das ich verwende, ist, wenn eine Variable in der Prüfung wie (j> 3 | ++ i> 3) oder (++ i> 3 | modifiziertGlobalAmongOtherThings () = true) geändert wird. Nicht allzu häufig.
AndSoYouCode
8
Ein anderes kanonisches Beispiel ist string == null || string.isEmpty();)
Peter Lawrey
83

| führt keine Kurzschlussauswertung in booleschen Ausdrücken durch. ||wird aufhören zu bewerten, ob der erste Operand wahr ist, wird es aber |nicht.

Darüber hinaus |kann die bitweise ODER-Verknüpfung für Byte / Short / Int / Long-Werte ausgeführt werden. ||kann nicht.

Michael Myers
quelle
Geben Sie eine vollständige Antwort und ich werde es akzeptieren. Bisher sind Sie der Erste, der diesen Aspekt aufgreift.
John Meagher
Fehlender bitweiser Aspekt von |
John Meagher
63

Um auf den anderen Antworten anhand eines Beispiels aufzubauen, ist das Kurzschließen bei den folgenden Defensivprüfungen von entscheidender Bedeutung:

if (foo == null || foo.isClosed()) {
    return;
}

if (bar != null && bar.isBlue()) {
    foo.doSomething();
}

Die Verwendung von |und &könnte dazu führen, NullPointerExceptiondass hier geworfen wird.

Paul Bellora
quelle
Wenn Sie das NullObject-Muster anwenden würden, würde dies die Antwort nicht negieren (oder vielmehr negieren). Außerdem würde ich sagen, dass die Überprüfung, ob das Foo blau ist, etwas internes für Foo ist. Wenn es blau ist, sollte doSomething nichts tun.
nicodemus13
@ nicodemus13 - gute Punkte, obwohl das Null-Objekt-Muster nur manchmal wünschenswert ist und der Körper etwas anderes als ein anderer Aufruf sein könnte foo. Peter Lawreys "kanonisches Beispiel" ist das beste.
Paul Bellora
@ Khan: Ja, ich war ziemlich pernickety und das Null-Objekt ist nicht immer geeignet. Ich habe es mir einfach zur Gewohnheit gemacht, Dinge unbewusst umzugestalten. An Ihrer Antwort ist nichts besonders Falsches.
nicodemus13
39

Logisch ||und &&überprüfen Sie die rechte Seite nur bei Bedarf. Die |und &überprüfen Sie beide Seiten jedes Mal.

Beispielsweise:

int i = 12;
if (i == 10 & i < 9) // It will check if i == 10 and if i < 9
...

Schreiben Sie es um:

int i = 12;
if (i == 10 && i < 9) // It will check if i == 10 and stop checking afterward because i != 10
...

Ein anderes Beispiel:

int i = 12;
if (i == 12 | i > 10) // It will check if i == 12 and it will check if i > 10
...

Schreiben Sie es um:

int i = 12;
if (i == 12 || i > 10) // It will check if i == 12, it does, so it stops checking and executes what is in the if statement
...
Dair
quelle
18

Beachten Sie auch eine häufige Gefahr: Die nicht faulen Operatoren haben Vorrang vor den faulen, also:

boolean a, b, c;
a || b && c; //resolves to a || (b && c)
a | b && c; //resolves to (a | b) && c

Seien Sie vorsichtig beim Mischen.

Herr Smith
quelle
15

Neben dem Kurzschließen ist auch zu beachten, dass eine bitweise Logikoperation für Werte, die nicht 0 oder 1 sein können, eine ganz andere Bedeutung hat als die bedingte Logik. Während es normalerweise für |und gleich ist ||, mit &und &&Sie erhalten sehr unterschiedliche Ergebnisse (zB 2 & 4ist 0 / false während2 && 4 1 / wahr ist).

Wenn das, was Sie von einer Funktion erhalten, tatsächlich ein Fehlercode ist und Sie auf Nicht-0-Ness testen, kann dies ziemlich wichtig sein.

Dies ist in Java nicht so ein Problem, bei dem Sie explizit boolesch typisieren oder mit 0 oder ähnlichem vergleichen müssen, aber in anderen Sprachen mit ähnlicher Syntax (C / C ++ et al.) Kann es ziemlich verwirrend sein.

Beachten Sie auch, dass & und | kann nur auf ganzzahlige Werte angewendet werden und nicht auf alles, was einem booleschen Test entsprechen kann. Auch in Nicht-Java-Sprachen gibt es einige Dinge, die als Boolescher Wert mit einem impliziten != 0Vergleich verwendet werden können (Zeiger, Gleitkommazahlen, Objekte mit einem operator bool()usw.), und bitweise Operatoren sind in diesen Kontexten fast immer unsinnig.

flauschige
quelle
3
Ich bin froh, dass zumindest jemand den ganzen Zweck der Existenz bitweiser Operatoren erwähnt hat.
Ulidtko
9

Das einzige Mal, wenn Sie |oder &anstelle von ||oder verwenden würden&& ist, wenn Sie sehr einfache boolesche Ausdrücke haben und die Kosten für Abkürzungen (dh einen Zweig) höher sind als die Zeit, die Sie sparen, wenn Sie die späteren Ausdrücke nicht auswerten.

Dies ist jedoch eine Mikrooptimierung, die nur im niedrigsten Code von Bedeutung ist.

Peter Lawrey
quelle
1
Es wäre interessant, ob der Compiler dies in einigen Fällen automatisch tut.
Starblue
Vielleicht könnte die JIT, aber der Compiler tendiert dazu, sich nur mit einfachen Optimierungen zu befassen.
Peter Lawrey
2
Ja, ich habe auch Situationen gesehen, in denen | ist erheblich schneller als der Verzweigungs-Overhead von ||, insbesondere bei CPUs ohne oder mit eingeschränkter Verzweigungsvorhersage. Es ist selten, aber nicht ungewöhnlich. Einer meiner Mitarbeiter geriet in einem Code mit einem Auftragnehmer in einen Rückfallkrieg, weil er | (korrekt) verwendete und der Auftragnehmer dachte immer wieder, das sei "falsch".
flauschig
4
@Fluffy, die Moral der Geschichte ist, dass, wenn Sie etwas Kniffliges tun, kommentiert werden muss, warum Sie dies getan haben oder Ihre Bemühungen später verschwendet werden könnten. ;)
Peter Lawrey
1
Ja, irgendwann fügte er einen Kommentar hinzu (auf meinen Vorschlag, wie der Auftragnehmer dazu gebracht werden kann, das Problem nicht mehr zu beheben), und alles ist in Ordnung.
flauschig
8

|| ist der logische oder Operator während | ist der bitweise oder Operator.

boolean a = true;
boolean b = false;

if (a || b) {
}

int a = 0x0001;
a = a | 0x0002;
Jorge Ferreira
quelle
1
Fehlt das | ist auch ein nicht kurzschließender boolescher Operator.
John Meagher
2
@ John Meagher: Das ist implizit, da es bitweise ist .
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
@ L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ Wie haben Sie Ihren Namen in Ihrem Profil anders gestaltet?
UdayKiran Pulipati
8

a | b: bewerte b auf jeden Fall

a || b: bewerte b nur, wenn a als falsch ausgewertet wird

user18596
quelle
7

Zusätzlich zu der Tatsache, dass | ist ein bitweiser Operator: || ist ein Kurzschlussoperator - wenn ein Element falsch ist, werden die anderen nicht überprüft.

 if(something || someotherthing)
 if(something | someotherthing)

wenn etwas WAHR ist, || wird nichts auswerten, während | Wird besorgt. Wenn die Variablen in Ihren if-Anweisungen tatsächlich Funktionsaufrufe sind, verwenden Sie || spart möglicherweise viel Leistung.

Michael Stum
quelle
Warum würden Sie jemals | verwenden? in einer if-Anweisung. || ist boolesch, | ist nicht, | wäre nur boolesch, wenn Sie bereits an zwei booleschen Werten arbeiten.
FlySwat
Dies ist die erste Antwort, um alles zu bekommen.
John Meagher
Diese Antwort ist falsch. Wenn etwas FALSE ist, fahren beide Operatoren mit dem nächsten Operanden fort. Der Unterschied entsteht nur, wenn der erste Operand wahr ist.
Michael Myers
Schade, dass es ein absolut lächerliches Beispiel gibt.
FlySwat
Ich habe keine Ahnung, warum jemand | verwenden würde oder & in einer if-Anweisung für einen einfachen booleschen Vergleich, aber es ist vollkommen legal, und ich habe tatsächlich Beispiele dafür gesehen, als ich anfing, Programmieren zu lernen.
Michael Stum
3
| is the binary or operator

|| is the logic or operator
Lucas S.
quelle
2
Fehlt das | ist auch ein nicht kurzschließender boolescher Operator.
John Meagher
3

Die Operatoren ||und &&werden als bedingte Operatoren bezeichnet , während |und &als bitweise Operatoren bezeichnet werden . Sie dienen verschiedenen Zwecken.

Bedingte Operatoren funktionieren nur mit Ausdrücken, die statisch ausgewertet werden boolean sowohl auf der linken als auch auf der rechten Seite .

Bitweise Operatoren funktionieren mit beliebigen numerischen Operanden.

Wenn Sie einen logischen Vergleich durchführen möchten, sollten Sie bedingte Operatoren verwenden , da Sie Ihrem Code eine Art Typensicherheit hinzufügen.

Bruno Reis
quelle
Ähm, |und &sind auch bedingte Operatoren. Bitte beachten Sie den Link in meinem Kommentar zum Originalbeitrag.
Luftkissenfahrzeug voller Aale
@Hovercraft Full Of Aale: Diese Tabelle ist etwas irreführend; Sie werden NUR im Zusammenhang mit booleschen Werten als bedingte Operatoren bezeichnet, bei denen sie mathematisch äquivalenten eifrigen logischen Operatoren entsprechen. Wenn Sie anfangen, sich mit Dingen zu befassen, die andere Werte als 0 oder 1 haben, oder mit Gleitkommawerten oder Zeigern oder was auch immer, bricht der Vergleich zusammen.
flauschig
@fluffy: Das Diagramm ist nicht irreführend, da es sich nur um boolesche Operatoren handelte. Dass das |und &als bitweise Operatoren verwendet werden kann, ist ein völlig anderes Problem.
Luftkissenfahrzeug voller Aale
1
Es wäre genauer, sie als bitweise Operatoren zu bezeichnen, die für boolesche Werte verwendet werden, und nicht als boolesche Operatoren. Sie sind einfach mathematisch äquivalent, wenn es nur ein einziges Bit gibt.
flauschig
2

Eine Randnotiz: Java hat | = aber kein || =

Ein Beispiel dafür, wann Sie || verwenden müssen ist, wenn der erste Ausdruck ein Test ist, um zu sehen, ob der zweite Ausdruck explodieren würde. zB mit einem einzigen | Im folgenden Fall kann es zu einer NPE kommen.

public static boolean isNotSet(String text) {
   return text == null || text.length() == 0;
}
Peter Lawrey
quelle
2

Die anderen Antworten haben den funktionalen Unterschied zwischen den Operatoren gut abgedeckt, aber die Antworten könnten für nahezu jede einzelne C-abgeleitete Sprache gelten, die heute existiert. Die Frage ist markiert mitund so werde ich mich bemühen, spezifisch und technisch für die Java-Sprache zu antworten.

&und |können entweder ganzzahlige bitweise Operatoren oder boolesche logische Operatoren sein. Die Syntax für die bitweisen und logischen Operatoren ( §15.22 ) lautet:

AndExpression:
  EqualityExpression 
  AndExpression & EqualityExpression

ExclusiveOrExpression:
  AndExpression 
  ExclusiveOrExpression ^ AndExpression

InclusiveOrExpression:
  ExclusiveOrExpression 
  InclusiveOrExpression | ExclusiveOrExpression

Die Syntax für EqualityExpressionist in §15.21 definiert , was eine RelationalExpressionDefinition in §15.20 erfordert , was wiederum erfordert ShiftExpressionund ReferenceTypein §15.19 bzw. §4.3 definiert ist. ShiftExpressionerfordert AdditiveExpressionin definierten §15.18 , die Definition der grundlegenden arithmetischen, unäre Operatoren etc. Drilldown weiter ReferenceTypebohrt nach unten in alle die verschiedenen Möglichkeiten , eine Art darzustellen. (Obwohl ReferenceTypedie primitiven Typen nicht enthalten sind, ist letztendlich die Definition der primitiven Typen erforderlich, da sie der Dimensionstyp für ein Array sein können, bei dem es sich um a handelt ReferenceType.)

Die bitweisen und logischen Operatoren haben die folgenden Eigenschaften:

  • Diese Operatoren haben unterschiedliche Vorrang, wobei &sie den höchsten Vorrang haben und| die niedrigste Priorität haben.
  • Jeder dieser Operatoren ist syntaktisch linksassoziativ (jede Gruppe von links nach rechts).
  • Jeder Operator ist kommutativ, wenn die Operandenausdrücke keine Nebenwirkungen haben.
  • Jeder Operator ist assoziativ.
  • Die bitweisen und logischen Operatoren können verwendet werden, um zwei Operanden vom numerischen Typ oder zwei Operanden vom Typ zu vergleichen boolean. Alle anderen Fälle führen zu einem Fehler bei der Kompilierung.

Die Unterscheidung, ob der Operator als bitweiser Operator oder als logischer Operator dient, hängt davon ab, ob die Operanden "in einen primitiven Integraltyp konvertierbar" sind ( §4.2 ) oder ob sie vom Typ sind booleanoder Boolean( §5.1.8 ).

Wenn die Operanden ganzzahlige Typen sind, wird für beide Operanden eine binäre numerische Heraufstufung ( §5.6.2 ) durchgeführt, wobei beide als longs oder ints für die Operation verbleiben . Der Typ der Operation ist der Typ der (heraufgestuften) Operanden. Zu diesem Zeitpunkt ist &bitweises UND, ^bitweises exklusives ODER und |bitweises inklusive ODER. ( §15.22.1 )

Wenn die Operanden booleanoder sind Boolean, werden die Operanden bei Bedarf einer Unboxing-Konvertierung unterzogen ( §5.1.8 ), und der Typ der Operation ist boolean. &führt dazu, truewenn beide Operanden sind true, ^führt dazu, truewenn beide Operanden unterschiedlich sind, und |führt dazu, truewenn einer der Operanden ist true. ( §15.22.2 )

Im Gegensatz dazu && ist der "Bedingte-Und-Operator" ( §15.23 ) und der "Bedingte-Und ||-Operator" ( §15.24 ). Ihre Syntax ist definiert als:

ConditionalAndExpression:
  InclusiveOrExpression 
  ConditionalAndExpression && InclusiveOrExpression

ConditionalOrExpression:
  ConditionalAndExpression 
  ConditionalOrExpression || ConditionalAndExpression

&&ist wie &, außer dass es nur den rechten Operanden auswertet, wenn der linke Operand ist true. ||ist wie |, außer dass es nur den rechten Operanden auswertet, wenn der linke Operand ist false.

Bedingt-Und hat die folgenden Eigenschaften:

  • Der Bedingungs- und Operator ist syntaktisch linksassoziativ (er gruppiert von links nach rechts).
  • Der Bedingungs- und Operator ist sowohl in Bezug auf Nebenwirkungen als auch in Bezug auf den Ergebniswert vollständig assoziativ. Das heißt, für alle Ausdrücke aund b, und die cBewertung des Ausdrucks ((a) && (b)) && (c)führt zu demselben Ergebnis, wobei dieselben Nebenwirkungen in derselben Reihenfolge auftreten wie die Bewertung des Ausdrucks (a) && ((b) && (c)).
  • Jeder Operand des Bedingungs- und Operators muss vom Typ booleanoder sein Boolean, sonst tritt ein Fehler bei der Kompilierung auf.
  • Der Typ eines Bedingungs- und Ausdrucks ist immer boolean .
  • Zur Laufzeit wird zuerst der linke Operandenausdruck ausgewertet. Wenn das Ergebnis einen Typ hat Boolean, wird es einer Unboxing-Konvertierung unterzogen ( §5.1.8 ).
  • Wenn der resultierende Wert ist false, ist der Wert des Bedingungs- und Ausdrucksfalse und der des rechten Operanden wird nicht ausgewertet.
  • Wenn der Wert des linken Operanden ist true, wird der rechte Ausdruck ausgewertet. Wenn das Ergebnis einen Typ hat Boolean, wird es einer Unboxing-Konvertierung unterzogen ( §5.1.8 ). Der resultierende Wert wird zum Wert der Bedingung und des Ausdrucks.
  • Somit &&berechnet das gleiche Ergebnis wie &auf booleanOperanden. Es unterscheidet sich nur dadurch, dass der Ausdruck des rechten Operanden eher bedingt als immer ausgewertet wird.

Conditional-Or hat folgende Eigenschaften:

  • Der Bedingungs- oder Operator ist syntaktisch linksassoziativ (er gruppiert von links nach rechts).
  • Der Bedingungs- oder Operator ist in Bezug auf beide Nebenwirkungen und den Ergebniswert vollständig assoziativ. Das heißt, für alle Ausdrücke a, bund c, Auswertung des Ausdrucks ((a) || (b)) || (c)erzeugt das gleiche Ergebnis, wobei die gleichen Nebenwirkungen in der gleichen Reihenfolge auftreten, wie Auswertung des Ausdrucks (a) || ((b) || (c)).
  • Jeder Operand des Bedingungs- oder Operators muss vom Typ booleanoder sein Boolean, da sonst ein Fehler bei der Kompilierung auftritt.
  • Der Typ eines Bedingungs- oder Ausdrucks ist immer boolean.
  • Zur Laufzeit wird zuerst der linke Operandenausdruck ausgewertet. Wenn das Ergebnis einen Typ hat Boolean, wird es einer Unboxing-Konvertierung unterzogen ( §5.1.8 ).
  • Wenn der resultierende Wert ist true, ist der Wert des Bedingungs- oder Ausdrucks trueund der Ausdruck des rechten Operanden wird nicht ausgewertet.
  • Wenn der Wert des linken Operanden ist false, wird der rechte Ausdruck ausgewertet. Wenn das Ergebnis einen Typ hat Boolean, wird es einer Unboxing-Konvertierung unterzogen ( §5.1.8 ). Der resultierende Wert wird zum Wert der Bedingung oder des Ausdrucks.
  • Somit ||berechnet das gleiche Ergebnis wie |am booleanoder BooleanOperanden. Es unterscheidet sich nur dadurch, dass der Ausdruck des rechten Operanden eher bedingt als immer ausgewertet wird.

Kurz gesagt, wie @JohnMeagher hat wiederholt in den Kommentaren darauf hingewiesen, &und |ist in der Tat nicht-Kurzschließen Booleschen Operatoren in dem speziellen Fall der Operanden entweder booleanoder Boolean. Bei bewährten Verfahren (dh keine Nebenwirkungen) ist dies ein geringfügiger Unterschied. Wenn die Operanden jedoch nicht booleans oder Booleans sind, verhalten sich die Operatoren sehr unterschiedlich: Bitweise und logische Operationen lassen sich auf der hohen Ebene der Java-Programmierung einfach nicht gut vergleichen.

Brian S.
quelle
2

1). (Ausdruck1 | Ausdruck2), | Der Operator wertet expression2 aus, unabhängig davon, ob das Ergebnis von expression1 wahr oder falsch ist.

Beispiel:

class Or 
{
    public static void main(String[] args) 
    {
        boolean b=true;

        if (b | test());
    }

    static boolean test()
    {
        System.out.println("No short circuit!");
        return false;
    }
}

2). (Ausdruck1 || Ausdruck2), || Der Operator wertet expression2 nicht aus, wenn expression1 wahr ist.

Beispiel:

class Or 
{
    public static void main(String[] args) 
    {
        boolean b=true;

        if (b || test())
        {
            System.out.println("short circuit!");
        }
    }

    static boolean test()
    {
        System.out.println("No short circuit!");
        return false;
    }
}
Veeresh
quelle
1

|| Gibt einen booleschen Wert zurück, indem zwei Werte ODER-verknüpft werden (aus diesem Grund wird er als LOGICAL oder bezeichnet).

IE:

if (A || B) 

Würde true zurückgeben, wenn entweder A oder B wahr ist, oder false, wenn beide falsch sind.

| ist ein Operator, der eine bitweise Operation für zwei Werte ausführt. Um die bitweisen Operationen besser zu verstehen, können Sie hier lesen:

http://en.wikipedia.org/wiki/Bitwise_operation

FlySwat
quelle
1

Ein Hauptunterschied ist, dass || und && weisen "Kurzschluss" auf, sodass die RHS nur bei Bedarf ausgewertet wird.

Zum Beispiel

if (a || b) {
    path1...
} else {
    path2..
}

Wenn a wahr ist, wird b nicht getestet und Pfad1 wird ausgeführt. Wenn | verwendet wurde, würden dann beide Seiten ausgewertet, auch wenn 'a' wahr ist.

Weitere Informationen finden Sie hier und hier .

Hoffe das hilft.

Alex H.
quelle
1

Ein Kurzschluss kann nützlich sein. Manchmal möchten Sie sicherstellen, dass zwei Ausdrücke ausgewertet werden. Angenommen, Sie haben eine Methode, mit der ein Objekt aus zwei separaten Listen entfernt wird. Vielleicht möchten Sie so etwas tun:

class foo {

    ArrayList<Bar> list1 = new ArrayList<Bar>();
    ArrayList<Bar> list2 = new ArrayList<Bar>();

    //Returns true if bar is removed from both lists, otherwise false.
    boolean removeBar(Bar bar) {
        return (list1.remove(bar) & list2.remove(bar));
    }
}

Wenn Ihre Methode stattdessen den bedingten Operanden verwendet, kann das Objekt nicht aus der zweiten Liste entfernt werden, wenn die erste Liste false zurückgibt.

//Fails to execute the second remove if the first returns false.
boolean removeBar(Bar bar) {
    return (list1.remove(bar) && list2.remove(bar));
}

Es ist nicht besonders nützlich, und (wie bei den meisten Programmieraufgaben) können Sie es mit anderen Mitteln erreichen. Dies ist jedoch ein Anwendungsfall für bitweise Operanden.

ktbiz
quelle
1

Der grundlegende Unterschied zwischen ihnen ist, dass | konvertiert zuerst die Werte in binär und führt dann die bitweise oder Operation aus. Inzwischen || konvertiert die Daten nicht in Binärdaten und führt nur den Ausdruck oder im ursprünglichen Zustand aus.

int two = -2; int four = -4;
result = two | four; // bitwise OR example

System.out.println(Integer.toBinaryString(two));
System.out.println(Integer.toBinaryString(four));
System.out.println(Integer.toBinaryString(result));

Output:
11111111111111111111111111111110
11111111111111111111111111111100
11111111111111111111111111111110

Lesen Sie mehr: http://javarevisited.blogspot.com/2015/01/difference-between-bitwsie-and-logical.html#ixzz45PCxdQhk

Avinash Nath
quelle
Unwahr, wenn die Operanden Boolesche Werte und dumme Formatierungen sind.
Marquis von Lorne
2
Dies war hilfreich für mich, um zu verstehen, warum Long.valueOf (100 | 200) = 236. Hier ist der Grund: 0 1 1 0 0 1 0 0 | 1 1 0 0 1 0 0 0 = 1 1 1 0 1 1 0 0 = 128 64 32 0 8 4 0 0 = 236
donlys
1

Als ich diese Frage hatte, habe ich Testcode erstellt, um eine Vorstellung davon zu bekommen.

public class HelloWorld{

   public static boolean bool(){
      System.out.println("Bool");
      return true;
   }

   public static void main(String []args){

     boolean a = true;
     boolean b = false;

     if(a||bool())
     {
        System.out.println("If condition executed"); 
     }
     else{
         System.out.println("Else condition executed");
     }

 }
}

In diesem Fall ändern wir nur den Wert auf der linken Seite der if-Bedingung, indem wir a oder b hinzufügen.

|| Szenario, wenn die linke Seite wahr ist [if (a || bool ())]

Ausgabe "If condition executed"

|| Szenario, wenn die linke Seite falsch ist [if (b || bool ())]

Ausgabe-

Bool
If condition executed

Conclusion of || Bei Verwendung ||prüft die rechte Seite nur, wenn die linke Seite falsch ist.

| Szenario, wenn die linke Seite wahr ist [if (a | bool ())]

Ausgabe-

Bool
If condition executed

| Szenario, wenn die linke Seite falsch ist [if (b | bool ())]

Ausgabe-

Bool
If condition executed

Conclusion of | |Überprüfen Sie bei der Verwendung sowohl die linke als auch die rechte Seite.

JustCode
quelle
0

| = bitweise oder || = Logik oder

MagicKat
quelle
2
Fehlt das | ist auch ein nicht kurzschließender boolescher Operator.
John Meagher
0

Normalerweise verwende ich, wenn es einen Operator vor und nach dem Inkrement gibt. Sehen Sie sich den folgenden Code an:

package ocjpPractice;
/**
 * @author tithik
 *
 */
public class Ex1 {

    public static void main(String[] args) {
    int i=10;
    int j=9;
    int x=10;
    int y=9;
    if(i==10 | ++i>j){
        System.out.println("it will print in first if");  
        System.out.println("i is: "+i);
    }

    if(x==10 ||++x>y){
        System.out.println("it will print in second if");   
        System.out.println("x is: "+x);
    }
    }
}

Ausgabe:

Es wird zuerst gedruckt, wenn
i: 11 ist.

Es wird als zweites gedruckt, wenn
x: 10 ist

Beide ifBlöcke sind gleich, aber das Ergebnis ist unterschiedlich. Wenn dies |der Fall ist , werden beide Bedingungen ausgewertet. Wenn dies jedoch ||der Fall ist , wird die zweite Bedingung nicht bewertet, da die erste Bedingung bereits erfüllt ist.

Tithi
quelle
1
Ich finde das sehr verwirrend
NimChimpsky
0

Es gibt viele Anwendungsfälle, die darauf hinweisen, warum Sie sich ||eher für als für entscheiden sollten |. In einigen Anwendungsfällen muss der| Operator verwendet werden, um alle Bedingungen zu überprüfen.

Wenn Sie beispielsweise die Formularüberprüfung überprüfen und dem Benutzer alle ungültigen Felder mit Fehlertexten anzeigen möchten und nicht nur ein erstes ungültiges Feld.

|| Betreiber wäre,

   if(checkIfEmpty(nameField) || checkIfEmpty(phoneField) || checkIfEmpty(emailField)) {
      // invalid form with one or more empty fields
   }

   private boolean checkIfEmpty(Widget field) {
      if(field.isEmpty()) {
        field.setErrorMessage("Should not be empty!");
        return true;
      }
      return false;
   }

Wenn der Benutzer mit dem obigen Snippet das Formular mit ALLEN leeren Feldern sendet, wird NUR nameFieldeine Fehlermeldung angezeigt. Aber wenn Sie es ändern,

   if(checkIfEmpty(nameField) | checkIfEmpty(phoneField) | checkIfEmpty(emailField)) {
      // invalid form with one or more empty fields
   }

Unabhängig von den trueBedingungen wird in jedem Feld die richtige Fehlermeldung angezeigt .

Bharath Mg
quelle
0

Nach sorgfältigem Lesen dieses Themas ist mir immer noch unklar, ob die Verwendung |als logischer Operator den Java-Musterpraktiken entspricht.

Ich habe kürzlich den Code in einer Pull-Anfrage geändert, in der ein Kommentar wo adressiert wurde

if(function1() | function2()){
  ...
}

musste geändert werden auf

boolean isChanged = function1();
isChanged |= function2();
if (isChanged){
  ...
}

Was ist die tatsächlich akzeptierte Version?

Java - Dokumentation ist nicht zu erwähnen , |als logischer Nicht-Kurzschluss OR - Operator.

Nicht an einer Abstimmung interessiert, sondern mehr daran, den Standard herauszufinden?! Beide Codeversionen werden kompiliert und funktionieren wie erwartet.

Dan M.
quelle
-1

|| ist ein logisches oder und | ist ein bisschen weise oder.

Steve Moyer
quelle
-2

| ist ein bitweiser Operator. || ist ein logischer Operator.

Man nimmt zwei Bits und oder sie.

Man wird die Wahrheit bestimmen (dies ODER das). Wenn dies wahr ist oder das wahr ist, dann ist die Antwort wahr.

Oh, und verdammt, die Leute beantworten diese Fragen schnell.

scubabbl
quelle