Który zestaw jest zwarty i co dokładnie oznacza, że złożone wyrażenie warunkowe jest zwarte?
public static void main(String[] args) {
int x, y, z;
x = 10;
y = 20;
z = 30;
// T T
// T F
// F T
// F F
//SET A
boolean a = (x < z) && (x == x);
boolean b = (x < z) && (x == z);
boolean c = (x == z) && (x < z);
boolean d = (x == z) && (x > z);
//SET B
boolean aa = (x < z) & (x == x);
boolean bb = (x < z) & (x == z);
boolean cc = (x == z) & (x < z);
boolean dd = (x == z) & (x > z);
}
java
logical-operators
Aaron
źródło
źródło
Odpowiedzi:
&&
I||
operatorzy „zwarcie”, co oznacza, że nie ocenia prawą stronę, jeśli nie jest to konieczne.Te
&
i|
operatorzy, stosowany jako operatorów logicznych, zawsze oceniać obie strony.Dla każdego operatora występuje tylko jeden przypadek zwarcia i są to:
false && ...
- nie trzeba wiedzieć, co to jest prawa strona, ponieważ wynik może być tylkofalse
bez względu na wartośćtrue || ...
- nie trzeba wiedzieć, co to jest prawa strona, ponieważ wynik może być tylkotrue
bez względu na wartośćPorównajmy zachowanie na prostym przykładzie:
Druga wersja używa operatora nie powodującego zwarcia
&
i wyrzuciNullPointerException
ifinput
isnull
, ale pierwsza wersja zwrócifalse
bez wyjątku.źródło
Zestaw A wykorzystuje operatory logiczne zwierające.
„Zwarcie” oznacza w kontekście operatorów boolowskich to, że dla zbioru wartości logicznych b1, b2, ..., bn wersje zwarciowe zaprzestaną oceny, gdy tylko pierwsza z tych wartości logicznych stanie się prawdziwa (|| ) lub fałsz (&&).
Na przykład:
źródło
&&
,||
działa inaczej i zaprzestanie oceny pierwszego operandu, który zwróci wartość true;)&&
,||
,&
i|
oceniają lewej do prawej. Dla zestawu wartości logicznych b1, b2, ..., bn wersje zwarciowe przestaną oceniać, gdy pierwsza z tych wartości logicznych ma wartość true (||
) lub false (&&
). Tak, zasada jest;)Zwarcie oznacza, że drugi operator nie zostanie sprawdzony, jeśli pierwszy operator zadecyduje o wyniku końcowym.
Np. Wyrażenie to: True || Fałszywe
W przypadku || potrzebujemy tylko jednej strony, aby była True. Więc jeśli lewa strona jest prawdą, nie ma sensu sprawdzać prawej strony, a zatem nie będzie to w ogóle sprawdzane.
Podobnie, fałsz i prawda
W przypadku && obie strony muszą być Prawdą. Więc jeśli lewa strona jest fałszywa, nie ma sensu sprawdzać prawej strony, odpowiedź musi być fałszywa. I stąd w ogóle nie będzie to sprawdzane.
źródło
Ten rodzaj spowoduje zwarcie, co oznacza, że jeśli
(x < z)
oszacuje jako fałsz, to ten ostatni nie zostanie oceniony,a
będzie fałszywy, w przeciwnym razie&&
również oceni(x == x)
.&
jest operatorem bitowym, ale także operatorem logicznym AND, który nie powoduje zwarcia.Możesz je przetestować w następujący sposób (zobacz, ile razy metoda jest wywoływana w każdym przypadku):
źródło
&
jest to tylko operator bitowy, ale to nieprawda. Jest to również operator logiczny „lub”.true & false
ocenia jako fałsz. Czy możesz wyjaśnić ten „boolowski” lub „operator”? Może nie rozumiem tego, co próbujesz powiedzieć.AND
, nieOR
! ietrue & false
jest poprawną składnią. -1 usunięto :)Mówiąc najprościej, zwarcie oznacza zatrzymanie oceny, gdy wiesz, że odpowiedź nie może się już zmienić. Na przykład, jeśli oceniasz łańcuch logicznych
AND
s i odkryjeszFALSE
pośrodku tego łańcucha, wiesz, że wynik będzie fałszywy, bez względu na wartości pozostałych wyrażeń w łańcuchu. To samo dotyczy łańcuchaOR
s: gdy odkryjesz aTRUE
, od razu znasz odpowiedź, więc możesz pominąć ocenę pozostałych wyrażeń.Wskazujesz Javie, że chcesz skracać, używając
&&
zamiast&
i||
zamiast|
. Pierwszy zestaw w Twoim poście to zwarcie.Zauważ, że to więcej niż próba zaoszczędzenia kilku cykli procesora: w takich wyrażeniach
zwarcie oznacza różnicę między poprawnym działaniem a awarią (w przypadku, gdy mystring jest zerowe).
źródło
Java udostępnia dwa interesujące operatory logiczne, których nie ma w większości innych języków komputerowych. Te wtórne wersje AND i OR są znane jako operatory logiczne zwarcia . Jak widać z poprzedniej tabeli, operator OR daje w wyniku prawdę, gdy A jest prawdziwe, bez względu na to, jakie jest B.
Podobnie operator AND daje w wyniku fałsz, gdy A jest fałszywe, bez względu na to, jakie jest B. Jeśli używasz formularzy
||
i&&
, zamiast|
i&
formy tych operatorów, Java nie przeszkadza, aby ocenić prawy operand sam. Jest to bardzo przydatne, gdy operand po prawej stronie zależy od tego, czy lewy jest prawdą lub fałszem, aby działał poprawnie.Na przykład poniższy fragment kodu pokazuje, w jaki sposób można skorzystać z oceny logicznej zwarcia, aby upewnić się, że operacja dzielenia będzie prawidłowa przed jej oceną:
Ponieważ
&&
używana jest forma zwarcia funkcji AND ( ), nie ma ryzyka spowodowania wyjątku w czasie wykonywania od dzielenia przez zero. Gdyby ten wiersz kodu został napisany przy użyciu pojedynczej&
wersji AND, obie strony musiałyby zostać ocenione, powodując wyjątek w czasie wykonywania, gdydenom
wynosi zero.Standardową praktyką jest stosowanie zwarciowych form AND i OR w przypadkach związanych z logiką Boole'a, pozostawiając wersje jednoznakowe wyłącznie dla operacji bitowych. Są jednak wyjątki od tej reguły. Weźmy na przykład pod uwagę następującą instrukcję:
Tutaj użycie pojedynczej
&
zapewnia, że operacja przyrostu zostanie zastosowana doe
tego, czyc
jest równa 1, czy nie.źródło
Logiczne LUB: - zwraca prawdę, jeśli przynajmniej jeden z operandów ma wartość true. Oba operandy są oceniane przed zastosowaniem operatora OR.
Short Circuit OR: - jeśli operand po lewej stronie zwraca prawdę, zwraca prawdę bez szacowania argumentu po prawej stronie.
źródło
Istnieje kilka różnic między operatorami
&
i&&
. Te same różnice dotyczą|
i||
. Najważniejszą rzeczą, o której należy pamiętać, jest to, że&&
jest to operator logiczny , który ma zastosowanie tylko do operandów boolowskich, a&
jest to operator bitowy , który ma zastosowanie zarówno do typów całkowitych, jak i logicznych.Za pomocą operacji logicznej można wykonać zwarcie, ponieważ w pewnych przypadkach (jak pierwszy operand
&&
bytufalse
lub pierwszy operand funkcji||
bytutrue
) nie musisz oceniać reszty wyrażenia. Jest to bardzo przydatne do wykonywania takich czynności, jak sprawdzanienull
przed uzyskaniem dostępu do pola lub metody oraz sprawdzanie potencjalnych zer przed podzieleniem przez nie. W przypadku wyrażenia złożonego każda część wyrażenia jest oceniana rekurencyjnie w ten sam sposób. Na przykład w następującym przypadku:Oceniane będą tylko zaznaczone fragmenty. Aby obliczyć
||
, najpierw sprawdź, czy7 == 8
jesttrue
. Gdyby tak było, prawa strona zostałaby całkowicie pominięta. Prawa strona sprawdza tylko, czy1 == 3
jestfalse
. Ponieważ tak jest,4 == 4
nie trzeba go sprawdzać, a wynikiem całego wyrażenia jestfalse
. Gdyby lewa strona byłatrue
np.7 == 7
Zamiast7 == 8
, cała prawa strona zostałaby pominięta, ponieważ całość||
wyrażenie byłobytrue
niezależnie.W przypadku operacji bitowych musisz oszacować wszystkie operandy, ponieważ tak naprawdę po prostu łączysz bity. Booleany są w rzeczywistości jednobitowymi liczbami całkowitymi w Javie (niezależnie od tego, jak działają elementy wewnętrzne) i to tylko zbieg okoliczności, że w tym jednym szczególnym przypadku można wykonać zwarcia dla operatorów bitowych. Powodem, dla którego nie można zwierać ogólnej liczby całkowitej
&
lub|
operacji, jest to, że niektóre bity mogą być włączone, a niektóre wyłączone w którymkolwiek z argumentów. Coś jak1 & 2
daje zero, ale nie możesz tego wiedzieć bez oceny obu operandów.źródło
Ponieważ używana jest forma zwarcia AND (&&), nie ma ryzyka spowodowania wyjątku w czasie wykonywania, gdy demon ma wartość zero.
Nr ref. Java 2 Fifth Edition autorstwa Herberta Schildta
źródło