J'ai une longue série de comparaisons à faire en Java et j'aimerais savoir si une ou plusieurs d'entre elles s'avèrent vraies. La chaîne de comparaisons était longue et difficile à lire, alors je l'ai interrompue pour plus de lisibilité et je suis automatiquement allée utiliser un opérateur de raccourci |=
plutôt que negativeValue = negativeValue || boolean
.
boolean negativeValue = false;
negativeValue |= (defaultStock < 0);
negativeValue |= (defaultWholesale < 0);
negativeValue |= (defaultRetail < 0);
negativeValue |= (defaultDelivery < 0);
Je m'attends negativeValue
à être vrai si l'une des valeurs par défaut <quelque chose> est négative. Est-ce valable? Fera-t-il ce que j'attends? Je n'ai pas pu le voir mentionné sur le site de Sun ou sur stackoverflow, mais Eclipse ne semble pas avoir de problème avec cela et le code se compile et s'exécute.
De même, si je voulais effectuer plusieurs intersections logiques, pourrais-je utiliser à la &=
place de &&
?
la source
||=
opérateur inexistant , mais il|=
s'agit de la forme de combinaison de l'opérateur ou du bit.|=
court-circuit serait incompatible avec d'autres opérateurs d'assignation composée, cara |= b;
ce ne serait pas la même chose quea = a | b;
, avec la mise en garde habituelle sur l'évaluationa
deux fois (si cela compte). Il me semble que la grande décision de comportement linguistique n'a pas été prise||=
, donc je rate votre point.Réponses:
le
|=
est un opérateur d'affectation de composé ( JLS 15.26.2 ) pour l'opérateur logique booléen|
( JLS 15.22.2 ); à ne pas confondre avec le conditionnel-or||
( JLS 15.24 ). Il existe également&=
et^=
correspondant à la version d'affectation composée de la logique booléenne&
et^
respectivement.En d'autres termes, pour
boolean b1, b2
, ces deux sont équivalents:La différence entre les opérateurs logiques (
&
et|
) et leurs équivalents conditionnels (&&
et||
) est que les premiers ne "court-circuitent" pas; ce dernier le font. C'est:&
et|
toujours évaluer les deux opérandes&&
et||
évaluer le bon opérande de manière conditionnelle ; l'opérande de droite n'est évalué que si sa valeur peut affecter le résultat de l'opération binaire. Cela signifie que l'opérande correct n'est PAS évalué lorsque:&&
évalue àfalse
false
)||
évalue àtrue
true
)Donc, pour revenir à votre question initiale, oui, cette construction est valide, et bien que
|=
n'est pas exactement un raccourci équivalent pour=
et||
, elle calcule ce que vous voulez. Comme le côté droit de l'|=
opérateur dans votre utilisation est une simple opération de comparaison d'entiers, le fait que|
ne court-circuite pas est insignifiant.Il existe des cas où un court-circuit est souhaité, voire nécessaire, mais votre scénario n'en fait pas partie.
Il est regrettable que contrairement à certains autres langages, Java n'ait pas
&&=
et||=
. Cela a été discuté dans la question Pourquoi Java n'a-t-il pas de versions d'assignation composée des opérateurs conditionnel et et conditionnel ou? (&& =, || =) .la source
|
Ce n'est pas un opérateur de "raccourci" (ou de court-circuit) de la façon dont || et && sont (en ce sens qu'ils n'évalueront pas le RHS s'ils connaissent déjà le résultat basé sur le LHS) mais il fera ce que vous voulez en termes de travail .
À titre d'exemple de la différence, ce code conviendra s'il
text
est nul:alors que ce ne sera pas:
(Évidemment, vous pouvez le faire
"".equals(text)
pour ce cas particulier - j'essaie simplement de démontrer le principe.)la source
Vous pourriez juste avoir une déclaration. Exprimé sur plusieurs lignes, il se lit presque exactement comme votre exemple de code, mais moins impératif:
Pour les expressions les plus simples, utiliser
|
peut être plus rapide que||
parce que même si cela évite de faire une comparaison, cela signifie utiliser une branche implicitement et cela peut être beaucoup plus cher.la source
Bien que cela puisse être excessif pour votre problème, la bibliothèque Guava a une bonne syntaxe avec
Predicate
s et évalue en court-circuit ou / etPredicate
s.Essentiellement, les comparaisons sont transformées en objets, emballées dans une collection, puis répétées. Pour ou prédicats, le premier vrai hit revient de l'itération, et vice versa pour et.
la source
S'il s'agit de lisibilité, j'ai le concept de séparation des données testées à partir de la logique de test. Exemple de code:
Le code semble plus détaillé et explicite. Vous pouvez même créer un tableau dans l'appel de méthode, comme ceci:
Elle est plus lisible que la «chaîne de comparaison» et présente également un avantage en termes de performances de court-circuit (au prix de l'allocation de tableau et de l'appel de méthode).
Edit: Encore plus de lisibilité peut être simplement obtenue en utilisant les paramètres varargs:
La signature de la méthode serait:
Et l'appel pourrait ressembler à ceci:
la source
C'est un ancien post, mais afin de donner une perspective différente aux débutants, je voudrais donner un exemple.
Je pense que le cas d'utilisation le plus courant pour un opérateur composé similaire serait
+=
. Je suis sûr que nous avons tous écrit quelque chose comme ceci:Quel était le but de cela? Le but était d'éviter le passe-partout et d'éliminer le code répétitif.
Donc, la ligne suivante fait exactement la même chose, évitant de taper la variable
b1
deux fois dans la même ligne.la source
longNameOfAccumulatorAVariable += 5;
vs.longNameOfAccumulatorAVariable = longNameOfAccumulatorVVariable + 5;
la source
negativeValue = defaultStock < 0 || defaultWholesale < 0
etc. Mis à part l'inefficacité de tous les emballages et emballages qui se déroulent ici, je ne trouve pas aussi facile de comprendre ce que votre code signifierait vraiment.|| logique booléenne OU
| OU au niveau du bit
| = Opérateur OU et d'affectation inclusif au niveau du bit
La raison pour laquelle | = ne court-circuite pas est parce qu'il fait un OU au niveau du bit OU pas un OU logique. C'est-à-dire:
Tutoriel pour les opérateurs Java
la source
|
est un OU au niveau du bit entier mais est également un OU logique - voir Spécification du langage Java 15.22.2.