Operator skrótu "or-assignment" (|=) w Javie
Mam do zrobienia długi zestaw porównań w Javie i chciałbym wiedzieć, czy jedno lub więcej z nich wyjdzie na jaw. Ciąg porównań był długi i trudny do odczytania, więc złamałem go dla czytelności i automatycznie poszedłem użyć operatora skrótu |=
zamiast negativeValue = negativeValue || boolean
.
boolean negativeValue = false;
negativeValue |= (defaultStock < 0);
negativeValue |= (defaultWholesale < 0);
negativeValue |= (defaultRetail < 0);
negativeValue |= (defaultDelivery < 0);
Oczekuję, że negativeValue
będzie prawdziwa, jeśli którakolwiek z domyślnych wartości
Podobnie, gdybym chciał wykonać kilka skrzyżowań logicznych, czy mógłbym użyć &=
zamiast &&
?
8 answers
|=
jest operatorem przypisania złożonego ( JLS 15.26.2) dla operatora logicznego boolean|
(JLS 15.22.2); nie mylić z warunkowym-lub ||
(JLS 15.24). Istnieją również &=
i ^=
odpowiadające złożonej wersji logicznego przypisania &
i ^
odpowiednio.
Innymi słowy, dla boolean b1, b2
te dwa są równoważne:
b1 |= b2;
b1 = b1 | b2;
Różnica między operatorami logicznymi (&
i |
) w porównaniu do ich warunkowych odpowiedników (&&
i ||
) jest to, że pierwsze nie "skracają", a drugie tak. Czyli:
-
&
oraz|
zawsze oceniaj oba operandy -
&&
i||
oceniają prawe operand warunkowo; prawe operand jest oceniane tylko wtedy, gdy jego wartość może wpłynąć na wynik operacji binarnej. Oznacza to, że właściwy operand nie jest oceniany, gdy:- lewy operand
&&
ocenia dofalse
- (ponieważ bez względu na to, do jakiego WŁAŚCIWEGO operandu jest ewaluowany, całe wyrażenie jest
false
)
- (ponieważ bez względu na to, do jakiego WŁAŚCIWEGO operandu jest ewaluowany, całe wyrażenie jest
- lewy operand
||
ocenia natrue
- (ponieważ bez względu na to, do jakiego WŁAŚCIWEGO operandu jest ewaluowany, całe wyrażenie jest
true
)
- (ponieważ bez względu na to, do jakiego WŁAŚCIWEGO operandu jest ewaluowany, całe wyrażenie jest
- lewy operand
Wracając więc do twojego pierwotnego pytania, tak, ten konstrukt jest prawidłowy i chociaż |=
nie jest dokładnie odpowiednikiem skrótu dla =
I ||
, to oblicza to, co chcesz. Ponieważ prawa strona operatora |=
w Twoim użyciu jest prostą operacją porównywania liczb całkowitych, fakt, że |
nie jest skrótem jest nieistotny.
Zdarzają się przypadki, kiedy krótszy obieg jest pożądany, a nawet wymagany, ale twój scenariusz nie jest jednym z nich.
Szkoda, że w przeciwieństwie do innych języków Java nie posiada &&=
i ||=
. Zostało to omówione w pytaniu dlaczego Java nie ma compound przypisanie wersji warunkowych-i i warunkowych-czy operatorów? (&&=, ||=).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:08
Nie jest operatorem" skrótu " (lub zwarcia) w taki sposób, że | / i & & są (w tym, że nie będą oceniać RHS, jeśli znają już wynik na podstawie LHS), ale zrobi to, co chcesz pod względem działa .
Jako przykład różnicy, ten kod będzie w porządku, jeśli text
jest null:
boolean nullOrEmpty = text == null || text.equals("")
Natomiast to nie będzie:
boolean nullOrEmpty = false;
nullOrEmpty |= text == null;
nullOrEmpty |= text.equals(""); // Throws exception if text is null
(Oczywiście możesz zrobić "".equals(text)
w tym konkretnym przypadku-staram się tylko zademonstrować zasadę.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-21 09:12:10
Możesz mieć tylko jedno oświadczenie. Wyrażony w wielu wierszach czyta prawie dokładnie tak, jak Twój przykładowy kod, tylko mniej imperatywny:
boolean negativeValue
= defaultStock < 0
| defaultWholesale < 0
| defaultRetail < 0
| defaultDelivery < 0;
Dla najprostszych wyrażeń, użycie |
może być szybsze niż ||
, ponieważ nawet jeśli unika się porównywania, oznacza użycie gałęzi w domyśle i to może być wielokrotnie droższe.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-17 18:31:54
Chociaż może to być przesada dla Twojego problemu, biblioteka Guava ma jakąś ładną składnię z Predicate
s i robi zwarcie oceny or / I Predicate
s.
Zasadniczo porównania są przekształcane w obiekty, pakowane do kolekcji, a następnie powtarzane. Dla predykatów or, pierwszy prawdziwy hit powraca z iteracji i odwrotnie Dla and.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-22 14:28:50
Jeśli chodzi o czytelność, mam pojęcie oddzielenia testowanych danych od logiki testowania. Przykład kodu:
// declare data
DataType [] dataToTest = new DataType[] {
defaultStock,
defaultWholesale,
defaultRetail,
defaultDelivery
}
// define logic
boolean checkIfAnyNegative(DataType [] data) {
boolean negativeValue = false;
int i = 0;
while (!negativeValue && i < data.length) {
negativeValue = data[i++] < 0;
}
return negativeValue;
}
Kod wygląda bardziej zwięzle i jasno. Można nawet utworzyć tablicę w wywołaniu metody, jak to:
checkIfAnyNegative(new DataType[] {
defaultStock,
defaultWholesale,
defaultRetail,
defaultDelivery
});
Jest bardziej czytelny niż 'comparison string' , a także ma przewagę wydajności zwarcia (kosztem alokacji tablicy i wywołania metody).
Edit: Jeszcze większą czytelność można po prostu osiągnąć za pomocą parametry varargs:
Podpis metody będzie:
boolean checkIfAnyNegative(DataType ... data)
A wywołanie może wyglądać tak:
checkIfAnyNegative( defaultStock, defaultWholesale, defaultRetail, defaultDelivery );
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-26 08:11:53
List<Integer> params = Arrays.asList (defaultStock, defaultWholesale,
defaultRetail, defaultDelivery);
int minParam = Collections.min (params);
negativeValue = minParam < 0;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-21 09:21:31
|| logiczny boolean OR
/ bitowe lub
| = bitowy inkluzywny operator OR i przypisania
Powodem, dla którego | = nie skraca się, jest to, że robi bitowe lub nie logiczne OR. To znaczy:
C |= 2 is same as C = C | 2
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-11 19:15:04
To stary post, ale w celu zapewnienia innej perspektywy dla początkujących, chciałbym podać przykład.
Myślę, że najczęstszym przypadkiem użycia podobnego operatora złożonego byłoby +=
. Jestem pewien, że wszyscy napisaliśmy coś takiego:
int a = 10; // a = 10
a += 5; // a = 15
Jaki był tego cel? Miało to na celu uniknięcie dwukrotnego zapisu zmiennej a
w tej samej linii. (Czy brakuje mi tu czegoś lepszego?)
Więc następny wiersz robi dokładnie to samo, unikając wpisywania zmiennej b1
dwa razy w ta sama linia.
b1 |= b2;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-17 08:53:57