Zastanawiam się tylko, dlaczego zwykle używamy logicznej OR ||
między dwoma logicznymi OR |
, a nie bitowymi OR , chociaż oba działają dobrze.
Mam na myśli, spójrz na następujące:
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
Czy możemy użyć |
zamiast ||
? To samo z &
i &&
.
java
bitwise-operators
Eng.Fouad
źródło
źródło
||
i&&
zwarcie podczas|
i&
są chętni.&&
i||
, ale nigdy&
|
. Jeśli robisz coś, co zależy od efektów ubocznych, nie rozumiem, dlaczego używasz czegoś takiego,(a & b | c)
ponieważ ktoś może łatwo pomyśleć „Mogę to zoptymalizować za pomocą zwartych wersji”.Odpowiedzi:
Jeśli użyjesz formularzy
||
i&&
, a nie formularzy|
i&
, Java nie będzie kłopotać się oceną samego operandu po prawej stronie.Jest to kwestia tego, czy chcesz zewrzeć ocenę, czy nie - przez większość czasu.
Dobrym sposobem zilustrowania zalet zwarcia byłoby rozważenie następującego przykładu.
Kolejną korzyścią, jak wspomnieli Jeremy i Peter, w przypadku zwarcia jest zerowa kontrola odniesienia:
więcej informacji
źródło
foo != null && foo.hasBar()
foo != null && foo.hasBar()
) lub szybsze (b || foo.timeConsumingCall()
). 99% programistów nie powinno jednak martwić się o ten poziom mikrooptymalizacji.string == null || string.isEmpty()
;)|
nie dokonuje oceny zwarcia w wyrażeniach boolowskich.||
przestanie oceniać, czy pierwszy operand jest prawdziwy, ale|
nie zrobi tego.Ponadto
|
można go użyć do wykonania operacji bitowej-LUB na wartościach bajt / short / int / long.||
Nie mogę.źródło
Tak więc, aby oprzeć się na innych odpowiedziach z przykładem, zwarcie jest kluczowe w następujących kontrolach obronnych:
Użycie
|
i&
zamiast tego może spowodowaćNullPointerException
wyrzucenie tutaj.źródło
foo
. „Kanoniczny przykład” Petera Lawreya jest najlepszy.Logiczne
||
i&&
sprawdź prawą stronę tylko w razie potrzeby.|
I&
sprawdzić zarówno za każdym razem po bokach.Na przykład:
Przepisz to:
Inny przykład:
Przepisz to:
źródło
Zwróć też uwagę na częstą pułapkę: operatorzy nie leniwi mają pierwszeństwo przed operatorami leniwymi, więc:
Zachowaj ostrożność podczas ich mieszania.
źródło
Oprócz zwarć należy również pamiętać, że wykonywanie operacji logiki bitowej na wartościach innych niż 0 lub 1 ma zupełnie inne znaczenie niż logika warunkowa. Chociaż zwykle jest to samo dla
|
i||
, z&
i&&
otrzymujesz bardzo różne wyniki (np.2 & 4
Jest 0 / fałsz, podczas gdy2 && 4
jest 1 / prawda).Jeśli rzecz, którą otrzymujesz z funkcji, jest w rzeczywistości kodem błędu i testujesz na wartość inną niż 0, może to mieć duże znaczenie.
Nie jest to tak duży problem w Javie, w której musisz jawnie pisać na klawiaturze, aby wstawić wartość logiczną lub porównać z 0 lub podobnymi, ale w innych językach o podobnej składni (C / C ++ i in.) Może być dość mylący.
Zauważ też, że & i | może mieć zastosowanie tylko do wartości typu całkowitoliczbowego, a nie do wszystkiego, co może być równoważne testowi boolowskiemu. Ponownie, w językach innych niż Java, istnieje wiele rzeczy, które mogą być użyte jako logiczne z niejawnym
!= 0
porównaniem (wskaźniki, zmiennoprzecinkowe, obiekty zoperator bool()
itd.), A operatory bitowe są prawie zawsze nonsensowne w tych kontekstach.źródło
Jedyny raz, którego użyjesz
|
lub&
zamiast||
lub&&
jest, gdy masz bardzo proste wyrażenia boolowskie, a koszt skrótu (tj. Oddziału) jest większy niż czas, który oszczędzasz, nie oceniając późniejszych wyrażeń.Jest to jednak mikrooptymalizacja, która rzadko ma znaczenie, z wyjątkiem kodu o najwyższym poziomie.
źródło
|| jest logicznym lub operatorem, podczas gdy | jest bitową lub operatorem.
źródło
a | b: w każdym przypadku oceń b
a || b: ocenia b tylko wtedy, gdy a ocenia na fałsz
źródło
Oprócz tego, że | jest operatorem bitowym: || jest operatorem zwarcia - gdy jeden element jest fałszywy, nie sprawdzi pozostałych.
jeśli coś jest PRAWDA, || nie oceni niczego, podczas gdy | zrobi. Jeśli zmienne w instrukcjach if są faktycznie wywołaniami funkcji, użyj || prawdopodobnie oszczędza dużo wydajności.
źródło
źródło
Operatorzy
||
i&&
nazywane są operatory warunkowe , natomiast|
i&
są nazywane bitowe operatorów . Służą do różnych celów.Operatory warunkowe działają tylko z wyrażeniami, które statycznie oceniają
boolean
na lewą i prawą stronę.Operatory bitowe działają z dowolnymi operandami numerycznymi.
Jeśli chcesz wykonać logiczne porównanie, powinieneś użyć operatorów warunkowych , ponieważ dodasz do kodu pewien rodzaj bezpieczeństwa typu.
źródło
|
a&
także są operatorami warunkowymi. Zobacz link w moim komentarzu do oryginalnego postu.|
i&
mogą być używane jako operatory bitowe, jest zupełnie odrębną kwestią.Uwaga dodatkowa: Java ma | = ale nie || =
Przykład, kiedy musisz użyć || ma miejsce, gdy pierwsze wyrażenie jest testem sprawdzającym, czy drugie wyrażenie wybuchłoby. np. za pomocą jednego | w poniższym przypadku może powstać NPE.
źródło
Inne odpowiedzi wykonały dobrą robotę, pokrywając różnicę funkcjonalną między operatorami, ale odpowiedzi mogą dotyczyć niemal każdego istniejącego obecnie języka C. Pytanie jest oznaczone tagiemJawa, więc postaram się odpowiedzieć konkretnie i technicznie na język Java.
&
i|
mogą być albo całkowitymi bitowymi operatorami, albo logicznymi operatorami logicznymi. Składnia dla operatorów bitowych i logicznych ( §15.22 ) jest następująca:Składnia
EqualityExpression
jest zdefiniowana w § 15.21 , który wymagaRelationalExpression
zdefiniowania w § 15.20 , który z kolei wymagaShiftExpression
iReferenceType
zdefiniowany odpowiednio w §15.19 i §4.3 .ShiftExpression
wymagaAdditiveExpression
zdefiniowanego w § 15.18 , który kontynuuje drążenie w dół, definiując podstawowe arytmetyki, operatory jednoargumentowe itp. drążyReferenceType
wszystkie różne sposoby reprezentowania typu. (ChociażReferenceType
nie obejmuje typów pierwotnych, ostatecznie jest wymagana definicja typów pierwotnych, ponieważ mogą one być typem wymiaru tablicy, którym jest aReferenceType
.)Operatory bitowe i logiczne mają następujące właściwości:
Rozróżnienie, czy operator służy jako operator bitowe lub operator logiczny zależy od tego, czy są to argumenty „przekształcić w pierwotnej integralną typu” ( §4.2 ), czy są one typu
boolean
lubBoolean
( §5.1.8 ).Jeśli operandy są typami integralnymi, promocja binarna numeryczna ( § 5.6.2 ) jest wykonywana na obu operandach, pozostawiając je jako
long
s lubint
s dla operacji. Typ operacji będzie typem (promowanych) operandów. W tym momencie&
będzie bitowe ORAZ,^
będzie bitowo wykluczające LUB, i|
będzie bitowo włącznie LUB. ( §15.22.1 )Jeśli operandy są
boolean
lubBoolean
, operandy zostaną poddane konwersji rozpakowywania, jeśli to konieczne ( §5.1.8 ), a typem operacji będzieboolean
.&
spowoduje,true
jeśli oba operandy sątrue
,^
spowoduje,true
że oba operandy będą różne, i|
spowoduje,true
że którykolwiek z nich jesttrue
. ( §15.22.2 )Natomiast
&&
jest „operatorem warunkowym” ( § 15.23 ) i||
„operatorem warunkowym” ( §15.24 ). Ich składnia jest zdefiniowana jako:&&
jest podobny&
, z tym wyjątkiem, że ocenia prawy operand tylko wtedy, gdy lewy jesttrue
.||
jest podobny|
, z tym wyjątkiem, że ocenia prawy operand tylko wtedy, gdy lewy jestfalse
.Warunkowe-I ma następujące właściwości:
Warunkowe-Lub ma następujące właściwości:
W skrócie, jak @JohnMeagher wielokrotnie zwracał uwagę w komentarzach,
&
i|
są w rzeczywistości, bez zwierania operatorów logicznych w przypadku konkretnego z argumentów będących alboboolean
alboBoolean
. Przy dobrych praktykach (tj. Bez efektów wtórnych) jest to niewielka różnica. Gdy argumenty nie sąboolean
S lubBoolean
s, jednak operatorzy zachowują się bardzo różnie: bitowe i operacje logiczne po prostu nie porównać również na wysokim poziomie programowania Java.źródło
1). (Wyrażenie1 | wyrażenie2), | operator oceni wyrażenie2 niezależnie od tego, czy wynik wyrażenia 1 jest prawdziwy, czy fałszywy.
Przykład:
2). (Wyrażenie 1 || wyrażenie 2), || operator nie oceni wyrażenia2, jeśli wyrażenie1 jest prawdziwe.
Przykład:
źródło
|| zwraca wartość logiczną poprzez OR'ing dwóch wartości (dlatego jest znany jako LOGICAL lub)
TO ZNACZY:
Zwróciłby wartość true, jeśli A lub B jest true, lub false, jeśli oba są false.
| jest operatorem, który wykonuje bitową operację na dwóch wartościach. Aby lepiej zrozumieć operacje bitowe, możesz przeczytać tutaj:
http://en.wikipedia.org/wiki/Bitwise_operation
źródło
Jedną z głównych różnic jest to, że || i && wykazują „zwarcie”, więc RHS będzie oceniany tylko w razie potrzeby.
Na przykład
Powyżej, jeśli a jest prawdą, to b nie będzie testowane, a ścieżka1 zostanie wykonana. Jeśli | został użyty, wówczas obie strony zostałyby ocenione, nawet jeśli „a” jest prawdziwe.
Zobacz tutaj i tutaj , aby uzyskać więcej informacji.
Mam nadzieję że to pomoże.
źródło
Przydatny może być brak zwarcia. Czasami chcesz się upewnić, że dwa wyrażenia oceniają. Załóżmy na przykład, że masz metodę, która usuwa obiekt z dwóch oddzielnych list. Możesz zrobić coś takiego:
Jeśli zamiast tego twoja metoda użyłaby argumentu warunkowego, nie powiodłoby się usunięcie obiektu z drugiej listy, jeśli pierwsza lista zwróciłaby wartość false.
Nie jest to niezwykle przydatne i (jak w przypadku większości zadań programistycznych) można to osiągnąć innymi środkami. Ale jest to przypadek użycia bitandów.
źródło
Podstawowa różnica między nimi polega na tym, że | najpierw konwertuje wartości na binarne, a następnie wykonuje operację bitową. Tymczasem || nie konwertuje danych na dane binarne i po prostu wykonuje wyrażenie lub wyrażenie w oryginalnym stanie.
Czytaj więcej: http://javarevisited.blogspot.com/2015/01/difference-between-bitwsie-and-logical.html#ixzz45PCxdQhk
źródło
Kiedy miałem to pytanie, stworzyłem kod testowy, aby dowiedzieć się o tym.
W tym przypadku zmieniamy tylko wartość po lewej stronie, jeśli warunek dodaje a lub b.
wynik
"If condition executed"
Wynik-
Conclusion of ||
Podczas używania||
prawa strona sprawdza tylko, gdy lewa strona jest fałszywa.Wynik-
Wynik-
Conclusion of |
Podczas używania|
sprawdź zarówno lewą, jak i prawą stronę.źródło
| = bitowe lub, || = logika lub
źródło
zwykle używam, gdy jest operator wstępnego i końcowego. Spójrz na następujący kod:
wynik:
oba
if
bloki są takie same, ale wynik jest inny. gdy będzie|
, oba warunki zostaną ocenione. Ale jeśli tak||
, nie oceni drugiego warunku, ponieważ pierwszy warunek jest już spełniony.źródło
Istnieje wiele przypadków użycia sugerujące, dlaczego należy udać się do
||
zamiast|
. Niektóre przypadki użycia muszą korzystać|
z operatorem, aby sprawdzić wszystkie warunki.Na przykład, jeśli chcesz sprawdzić sprawdzanie poprawności formularza i chcesz pokazać użytkownikowi wszystkie nieprawidłowe pola z tekstami błędów, a nie tylko pierwsze nieprawidłowe pole.
||
operator byłbyTak więc przy powyższym fragmencie, jeśli użytkownik prześle formularz ze WSZYSTKIMI pustymi polami, TYLKO
nameField
zostanie wyświetlony komunikat o błędzie. Ale jeśli zmienisz to na,Wyświetli odpowiedni komunikat o błędzie na każdym polu, niezależnie od
true
warunków.źródło
Po uważnym przeczytaniu tego tematu wciąż nie jest dla mnie jasne, czy używanie go
|
jako operatora logicznego jest zgodne z praktykami wzorcowymi Java.Niedawno zmodyfikowałem kod w żądaniu ściągnięcia adresując komentarz gdzie
musiał zostać zmieniony na
Jaka jest faktycznie zaakceptowana wersja?
Nie interesuje Cię głosowanie, a bardziej znalezienie standardu ?! Obie wersje kodu kompilują się i działają zgodnie z oczekiwaniami.
źródło
|| jest logiczne lub i jest nieco mądry lub.
źródło
Operatory Java
| jest bitowe lub, || jest logiczne lub.
źródło
Spojrzeć na:
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/operators.html
| jest bitowe włącznie OR
|| jest logiczne LUB
źródło
| jest operatorem bitowym. || jest operatorem logicznym.
Jeden bierze dwa bity i / lub je.
Ustalimy prawdę (to LUB to) Jeśli to prawda lub prawda, to odpowiedź jest prawdą.
Och, i niech ludzie szybko odpowiedzą na te pytania.
źródło