Jaka jest różnica między & i && w Javie?

167

Zawsze myślałem, że &&operator w Javie służy do sprawdzania, czy oba jego operandy boolowskie są true, a &operator jest używany do wykonywania operacji bitowych na dwóch typach liczb całkowitych.

Niedawno dowiedziałem się, że &operator może również służyć do sprawdzania, czy oba jego operandy boolowskie są true, jedyną różnicą jest to, że sprawdza operand RHS, nawet jeśli operand LHS jest fałszywy.

Czy &operator w Javie jest wewnętrznie przeciążony? A może kryje się za tym jakaś inna koncepcja?

Społeczność
źródło
Double wykonuje skrót, jeśli to możliwe.
Nicholas Hamilton

Odpowiedzi:

278

& <- weryfikuje oba operandy
&& <- przestaje oceniać, jeśli pierwszy argument ma wartość fałsz, ponieważ wynik będzie fałszywy

(x != 0) & (1/x > 1)<- oznacza to ocenę, (x != 0)a następnie ocenę (1/x > 1)i wykonanie &. problem polega na tym, że dla x = 0 spowoduje to zgłoszenie wyjątku.

(x != 0) && (1/x > 1)<- oznacza oceniaj (x != 0)i tylko jeśli jest to prawda, obliczaj (1/x > 1)więc jeśli masz x = 0, to jest to całkowicie bezpieczne i nie zgłosi żadnego wyjątku, jeśli (x! = 0) oszacuje jako fałsz, całość bezpośrednio oszacuje na fałsz bez oceniania (1/x > 1).

EDYTOWAĆ:

exprA | exprB<- oznacza to ocenę, exprAa następnie ocenę, exprBa następnie wykonanie |.

exprA || exprB<- oznacza to ocenę exprAi tylko wtedy, gdy jest to falsenastępnie ocena exprBi wykonanie ||.

ITroubs
źródło
7
Jaki jest powód napisania & lub | w oświadczeniu if? Nigdy nie będzie szybsze niż && i ||. Dlaczego chcemy sprawdzać drugi warunek, skoro już możemy mieć odpowiedź? Czy możesz podać realistyczny przykład?
Michu93,
14
@ Michu93: Jednym z przykładów może być sytuacja, w której drugim warunkiem jest wywołanie funkcji, które ma efekt uboczny, którego zawsze potrzebujesz. Ponieważ zwykle należy unikać skutków ubocznych, będą tylko rzadkie przypadki, w których będziesz tego potrzebować, i nie mogę w tej chwili wymyślić realistycznego przykładu.
Heinzi,
54

Poza tym, że nie jest leniwym oceniającym, oceniając oba operandy, myślę, że główne cechy operatorów bitowych porównują każdy bajt operandów, jak w poniższym przykładzie:

int a = 4;
int b = 7;
System.out.println(a & b); // prints 4
//meaning in an 32 bit system
// 00000000 00000000 00000000 00000100
// 00000000 00000000 00000000 00000111
// ===================================
// 00000000 00000000 00000000 00000100
suat
źródło
2
Pytanie dotyczy logicznych operacji boolowskich, a nie operacji bitowych.
Markiz Lorne,
21
@EJP To nadal pomaga pracownikom Google takim jak ja, którzy czytają tylko tytuł.
Ad Infinitum
29
boolean a, b;

Operation     Meaning                       Note
---------     -------                       ----
   a && b     logical AND                    short-circuiting
   a || b     logical OR                     short-circuiting
   a &  b     boolean logical AND            not short-circuiting
   a |  b     boolean logical OR             not short-circuiting
   a ^  b     boolean logical exclusive OR
  !a          logical NOT

short-circuiting        (x != 0) && (1/x > 1)   SAFE
not short-circuiting    (x != 0) &  (1/x > 1)   NOT SAFE
Torres
źródło
Dziękuję Andreas za edycję, może to drugie pytanie też pomoże: stackoverflow.com/questions/4014535/vs-and-vs
Torres
11

To zależy od rodzaju argumentów ...

W przypadku argumentów całkowitych pojedynczy znak ampersand („&”) jest operatorem „bitowym AND”. Podwójny ampersand („&&”) nie jest zdefiniowany dla niczego poza dwoma argumentami logicznymi.

W przypadku argumentów logicznych pojedynczy znak ampersand stanowi (bezwarunkowy) operator „logicznego AND”, podczas gdy podwójny ampersand („&&”) jest operatorem „warunkowym logicznym AND”. Oznacza to, że pojedynczy ampersand zawsze ocenia oba argumenty, podczas gdy podwójny ampersand ocenia drugi argument tylko wtedy, gdy pierwszy argument jest prawdziwy.

W przypadku wszystkich innych typów i kombinacji argumentów powinien wystąpić błąd w czasie kompilacji.

deweloper
źródło
9

&& jest operatorem zwarcia, a & jest operatorem AND.

Spróbuj tego.

    String s = null;
    boolean b = false & s.isEmpty(); // NullPointerException
    boolean sb = false && s.isEmpty(); // sb is false
Książę John Wesley
źródło
7

jest to określone w JLS (15.22.2) :

Gdy oba operandy a &, ^ lub | operator jest typu boolean lub Boolean, wówczas typ wyrażenia operatora bitowego jest logiczny. We wszystkich przypadkach operandy podlegają konwersji podczas rozpakowywania (§5.1.8) w razie potrzeby.

Dla &, wartość wyniku jest prawdziwa, jeśli obie wartości operandów są prawdziwe; w przeciwnym razie wynik jest fałszywy.

Dla ^, wartość wyniku jest prawdziwa, jeśli wartości argumentów są różne; w przeciwnym razie wynik jest fałszywy.

Dla |, wartość wyniku jest fałszywa, jeśli obie wartości operandów są fałszywe; w przeciwnym razie wynik jest prawdziwy.

„Sztuczka” polega na tym, że &jest to całkowity operator bitowy, a także logiczny operator logiczny . Dlaczego więc nie, traktowanie tego jako przykładu przeciążenia operatora jest rozsądne.

Andreas Dolk
źródło
7

Myślę, że moja odpowiedź może być bardziej zrozumiała:

Istnieją dwie różnice między &i &&.

Jeśli używają logicznego AND

&i &&może być logiczne AND, kiedy &lub &&w lewo i prawo wyrażenie doprowadzić wszystko prawda, cała operacja może być wynikiem prawda.

kiedy &i &&co logiczne AND, istnieje różnica:

gdy jest używane &&jako logiczne AND, jeśli wynik lewego wyrażenia jest fałszywy, prawe wyrażenie nie zostanie wykonane.

Weź przykład:

String str = null;

if(str!=null && !str.equals("")){  // the right expression will not execute

}

Jeśli używasz &:

String str = null;

if(str!=null & !str.equals("")){  // the right expression will execute, and throw the NullPointerException 

}

Inny przykład:

int x = 0;
int y = 2;
if(x==0 & ++y>2){
    System.out.print(“y=”+y);  // print is: y=3
}

int x = 0;
int y = 2;
if(x==0 && ++y>2){
    System.out.print(“y=”+y);  // print is: y=2
}

& może być używany jako operator bitowy

&może być używany jako ANDoperator bitowy , &&nie może.

Operator bitowy AND „&” daje 1 wtedy i tylko wtedy, gdy oba bity w jego operandach są równe 1. Jednakże, jeśli oba bity są równe 0 lub oba bity są różne, wtedy ten operator daje 0. Aby być bardziej precyzyjnym bitowym Operator AND „&” zwraca 1, jeśli którykolwiek z dwóch bitów to 1, i zwraca 0, jeśli którykolwiek z bitów ma wartość 0. 

Ze strony wiki:

http://www.roseindia.net/java/master-java/java-bitwise-and.shtml

samolot
źródło
4

„&&”: - jest operatorem logicznym AND, który tworzy logiczną wartość prawdy lub fałszu w oparciu o logiczną relację jego argumentów.

Na przykład: - Warunek1 i Warunek2

Jeśli Warunek1 jest fałszywy, to (Warunek1 i & Warunek2) zawsze będzie fałszywy, to jest powód, dla którego ten operator logiczny jest również nazywany operatorem zwarcia, ponieważ nie ocenia innego warunku. Jeśli Warunek 1 jest fałszywy, nie ma potrzeby oceniania Condtiton2.

Jeśli Warunek1 jest prawdziwy, to jest oceniany Warunek2, jeśli jest prawdziwy, to ogólny wynik będzie prawdziwy, w przeciwnym razie będzie fałszywy.

„&”: - jest operatorem bitowym AND. Generuje jedynkę (1) na wyjściu, jeśli oba bity wejściowe są jednością. W przeciwnym razie daje zero (0).

Na przykład:-

int a = 12; // binarna reprezentacja liczby 12 to 1100

int b = 6; // binarna reprezentacja liczby 6 to 0110

int c = (a & b); // binarna reprezentacja (12 i 6) to 0100

Wartość c wynosi 4.

w celach informacyjnych zapoznaj się z tym http://techno-terminal.blogspot.in/2015/11/difference-between-operator-and-operator.html

satynowy
źródło
3

&&i ||nazywane są operatorami zwarć. Gdy są używane, for ||- jeśli wartość pierwszego argumentu truewynosi do , wówczas pozostałe argumenty nie są obliczane. For &&- jeśli pierwszy operand ma wartość false, pozostałe z nich w ogóle nie są oceniane.

więc if (a || (++x > 0))w tym przykładzie zmienna x nie zostanie zwiększona, jeśli była true.

ACV
źródło
3

W przypadku wartości logicznych nie ma między nimi różnicy wyjściowej. Możesz zamienić && i & lub || i | i nigdy nie zmieni wyniku twojej wypowiedzi.

Różnica kryje się za sceną, w której informacje są przetwarzane. Kiedy poprawisz wyrażenie „(a! = 0) i (b! = 0)” dla a = 0 i b = 1, dzieje się tak:

left side: a != 0 --> false
right side: b 1= 0 --> true
left side and right side are both true? --> false
expression returns false

Kiedy piszesz wyrażenie, (a != 0) && ( b != 0)gdy a = 0 i b = 1, dzieje się tak:

a != 0 -->false
expression returns false

Mniej kroków, mniej przetwarzania, lepsze kodowanie, szczególnie podczas wykonywania wielu wyrażeń logicznych lub skomplikowanych argumentów.

Ryan
źródło
2
Zmieni ogólny wynik wyrażenia, jeśli operandy mają skutki uboczne.
Markiz Lorne,
3

Poza tym && i || ponieważ są zwarte, należy również rozważyć pierwszeństwo operatorów podczas mieszania dwóch form. Myślę, że nie będzie od razu widoczne dla każdego, że wynik 1 i wynik 2 zawierają różne wartości.

boolean a = true;
boolean b = false;
boolean c = false;

boolean result1 = a || b && c; //is true;  evaluated as a || (b && c)
boolean result2 = a  | b && c; //is false; evaluated as (a | b) && c
mgr326639
źródło
0

& jest operatorem bitowym oraz używanym do sprawdzania obu warunków, ponieważ czasami musimy ocenić oba warunki. Ale operator logiczny && przechodzi do drugiego warunku, gdy pierwszy warunek daje prawdę.

Yasir Shabbir Choudhary
źródło
0

wszystkie odpowiedzi są greati wydaje się, że nowięcej odpowiedzi, is needed ale po prostu chciałem zwrócić uwagę na coś na temat &&operatora wywołanegodependent condition

W wyrażeniach korzystających z operatora && warunek - nazwiemy go dependent condition- może wymagać, aby inny warunek był prawdziwy, aby ocena warunku zależnego miała znaczenie.

W takim przypadku warunek zależny należy umieścić po operatorze &&, aby zapobiec błędom.

Rozważ wyrażenie (i != 0) && (10 / i == 2). Stan zależny (10 / i == 2)musi operatora, aby zapobiec możliwości podziału przez zero.appear after&&

inny przykład (myObject != null) && (myObject.getValue() == somevaluse)

i jeszcze jedno: &&i ||są nazywane ocena zwarcie ponieważ drugi argument jest wykonywany lub oceniana argumentem nie do zonly iffirstnot sufficedeterminevalueexpression

Odnośniki: Java ™ How To Program (wczesne obiekty), wydanie dziesiąte

Basheer AL-MOMANI
źródło