&& (ET) et | | (OU) dans les instructions IF


J'ai le code suivant:

if(!partialHits.get(req_nr).containsKey(z) || partialHits.get(req_nr).get(z) < tmpmap.get(z)){  
    partialHits.get(z).put(z, tmpmap.get(z));  
}

partialHits est un HashMap.
Que se passera - t-il si la première déclaration est vraie? Java vérifiera-t-il toujours la deuxième instruction? Parce que pour que la première instruction soit vraie, le HashMap ne doit pas contenir la clé donnée, donc si la deuxième instruction est cochée, j'obtiendrai NullPointerException.
Donc, en termes simples, si nous avons le code suivant

if(a && b)  
if(a || b)

Serait Java vérifier b si a est faux dans le premier cas, et si a est vrai dans le second cas?

Author: Amr, 2009-11-25

9 answers

Non, il ne sera pas évalué. Et c'est très utile. Par exemple, si vous devez tester si une chaîne n'est pas nulle ou vide, vous pouvez écrire:

if (str != null && !str.isEmpty()) {
  doSomethingWith(str.charAt(0));
}

Ou l'inverse

if (str == null || str.isEmpty()) {
  complainAboutUnusableString();
} else {
  doSomethingWith(str.charAt(0));
}

Si nous n'avions pas de "courts-circuits" en Java, nous recevrions beaucoup de NullPointerExceptions dans les lignes de code ci-dessus.

 172
Author: Andreas_D, 2018-03-15 00:39:20

Java a 5 opérateurs de comparaison booléens différents: &, &&, |, ||, ^

& et & & "et" opérateurs | et || "ou" opérateurs, ^ est "xor"

Les simples vérifieront chaque paramètre, quelles que soient les valeurs, avant de vérifier les valeurs des paramètres. Les doubles vérifieront d'abord le paramètre left et sa valeur et si true (||) ou false (&&) laissez le second intact. Son compilcated? Un exemple simple devrait le rendre clair:

compte tenu de pour tous les exemples:

 String aString = null;

ET:

 if (aString != null & aString.equals("lala"))

Les deux paramètres sont vérifiés avant la fin de l'évaluation et une NullPointerException sera levée pour le deuxième paramètre.

 if (aString != null && aString.equals("lala"))

Le premier paramètre est vérifié et il renvoie false, donc le deuxième paramètre ne sera pas vérifié, car le résultat est de toute façon false.

La même chose pour OU:

 if (aString == null | !aString.equals("lala"))

Déclenchera également NullPointerException.

 if (aString == null || !aString.equals("lala"))

Le premier paramètre est vérifié et il renvoie true, donc le deuxième paramètre ne sera pas vérifié, car le résultat est de toute façon true.

XOR ne peut pas être optimisé, car il dépend des deux paramètres.

 58
Author: Hardcoded, 2013-05-15 07:46:11

Non il ne sera pas vérifié. Ce comportement est appelé short-circuit evaluation et est une fonctionnalité dans de nombreux langages, y compris Java.

 27
Author: Peter van der Heijden, 2009-11-25 10:04:21

Toutes les réponses ici sont excellentes mais, juste pour illustrer d'où cela vient, pour des questions comme celle-ci, il est bon d'aller à la source: la spécification du langage Java.

Section 15:23, Conditionnel Et de l'opérateur (&&), dit:

L'opérateur && est comme & (§15.22.2), mais n'évalue son opérande de droite que si la valeur de son opérande de gauche est vraie. [...] Au moment de l'exécution, l'expression de l'opérande de gauche est évaluée en premier [...] si la valeur résultante est false, la valeur de l'expression conditionnelle-and est false et l'expression de l'opérande de droite n'est pas évaluée. Si la valeur de l'opérande de gauche est true, alors l'expression de droite est évaluée [...] la valeur résultante devient la valeur de l'expression conditionnelle-et. Ainsi, && calcule le même résultat que sur le opérandes booléens. Il ne diffère que par le fait que l'expression de l'opérande de droite est évaluée conditionnellement plutôt que toujours.

Et de même, Section 15: 24, Conditionnel-Ou opérateur (||), dit:

L'opérateur || est comme | (§15.22.2), mais n'évalue son opérande de droite que si la valeur de son opérande de gauche est false. [...] Au moment de l'exécution, l'expression de l'opérande de gauche est évaluée en premier; [...] si la valeur est true, la valeur du conditionnel ou de l'expression est vraie et que la droite opérande expression n'est pas évaluée. Si la valeur de l'opérande de gauche est false, alors l'expression de droite est évaluer; [...] la valeur résultante devient la valeur de l'expression conditionnelle ou. Ainsi, / / calcule le même résultat que / sur les opérandes booléens ou booléens. Il ne diffère que par le fait que l'expression de l'opérande de droite est évaluée conditionnellement plutôt que toujours.

Un peu répétitif, peut-être, mais la meilleure confirmation de la façon dont ils fonctionnent exactement. De même l'opérateur conditionnel (?:) n'évalue que la "moitié" appropriée (moitié gauche si la valeur est vraie, moitié droite si c'est faux), permettant l'utilisation d'expressions comme:

int x = (y == null) ? 0 : y.getFoo();

Sans NullPointerException.

 19
Author: Cowan, 2009-11-25 10:15:50

Non, si a est vrai (dans un test or), b ne sera pas testé, car le résultat du test sera toujours vrai, quelle que soit la valeur de l'expression b.

Faites un test simple:

if (true || ((String) null).equals("foobar")) {
    ...
}

Sera pas jeter un NullPointerException!

 5
Author: romaintaz, 2009-11-25 09:53:18

Non ce ne sera pas le cas, Java court-circuitera et arrêtera l'évaluation une fois qu'il connaîtra le résultat.

 4
Author: abyx, 2009-11-25 09:53:42

Oui, l'évaluation de court-circuit pour les expressions booléennes est le comportement par défaut dans toute la famille de type C.

Un fait intéressant est que Java utilise également les & et | comme opérandes logiques (ils sont surchargés, avec des types int ce sont les opérations binaires attendues) pour évaluer tous les termes de l'expression, ce qui est également utile lorsque vous avez besoin des effets secondaires.

 4
Author: fortran, 2009-11-27 11:30:04

Court-circuit ici signifie que la deuxième condition ne sera pas évaluée.

If ( A && B ) entraînera un court-circuit si A est faux.

If ( A && B ) sera pas résultat en court-Circuit si A est Vrai.

If ( A || B ) entraînera un court-circuit si A est vrai.

If ( A || B ) sera pas résultat en court-circuit si A est Faux.

 4
Author: user3211238, 2014-06-13 15:02:49

On en revient à la différence de base entre & et &&, | et ||

BTW vous effectuez les mêmes tâches plusieurs fois. Je ne sais pas si l'efficacité est un problème. Vous pouvez supprimer une partie de la duplication.

Z z2 = partialHits.get(req_nr).get(z); // assuming a value cannout be null.
Z z3 = tmpmap.get(z); // assuming z3 cannot be null.
if(z2 == null || z2 < z3){   
    partialHits.get(z).put(z, z3);   
} 
 0
Author: Peter Lawrey, 2010-05-11 20:16:34