Supposons que j'ai un suppose maintenant que Si je les mettez les deux dans les supports Le La chose est que mon professeur a écrit sur ses remarques de cours que je devrais mettre la "variable plus probable pour recevoir un vrai" à gauche. P> Quelqu'un peut-il expliquer l'avantage? D'accord, je le mets à gauche ... Qu'est-ce que je gagne? Durée ? p> p> si code> condition: a code> est plus susceptible de recevoir une valeur vraie puis B code>, pourquoi est-ce que je me soucie de savoir lequel est à gauche? p> si code>, je sais (comme programmeur du code) que les deux parties sont nécessaires. P>
9 Réponses :
Selon Javadoc P>
the && et || Les opérateurs effectuent des opérations conditionnelles et conditionnelles à deux expressions booléennes. Ces opérateurs présentent un comportement "à court-circuit", ce qui signifie que le deuxième opérande est évalué que si nécessaire P> blockQuote>
Donc, si la déclaration vraie vient en premier dans la commande, elle court-circuit le deuxième opérande au moment de l'exécution. P>
véritables courts-circuits pour || code>, pas pour && code>. Faux courts-circuits pour && code>, pas pour || code>.
Si l'expression à gauche est vraie, il n'est pas nécessaire d'évaluer l'expression à droite, et il peut donc être optimisé au moment de l'exécution. Ceci est une technique appelée court-circuit. Donc, en plaçant l'expression plus susceptible d'être vrai à gauche, nous pouvons nous attendre à ce que notre programme fonctionne mieux que s'il s'agissait de l'inverse. P>
Décrire l'évaluation de court-circuit comme une optimisation implique qu'il est facultatif. Ce n'est pas. C'est le comportement mandaté par la norme.
Vous devez placer la condition plus susceptible d'être true d'abord parce que cela entraînera la déclaration IF à court-circuit. Ce qui signifie qu'il n'évaluera pas le reste de la déclaration de si, car il saura déjà que la réponse est vraie. Cela rend le code plus efficace.
Ceci est particulièrement utile lorsque votre instruction IF évalue des objets coûteux: P>
if(doExpensiveCheck1() || doExpensiveCheck2()) { }
je le mets à gauche ... Qu'est-ce que je gagne? Temps d'exécution fort>? P> blockQuote> parce que
|| code> opérateur en C ++ utilise Évaluation de court-circuit em> strong>.
I.E:B code> est évasé uniquement siA code> est évalué à unfalse code>. p>Toutefois, notez que, dans l'évaluation de court-circuit C ++, est garantie pour les types de données "intégrés" em> et non des types de données personnalisés. P>
@ron qu'est-ce que tu parles d'autre?
@ron - Je soupçonne que c'est exactement ce que signifie votre professeur.
@Als: D'accord, donc fondamentalement, la réponse est d'exécution! j'ai compris .
@ron La différence n'est pas seulement d'exécuter. Les || code> et && code> sont également une sorte de structure de contrôle. Pensez à ce code (pas très bon): si (a || this_will_crash_if_a_is_true ()) code>. Lorsque vous l'exécutez avec A == 1 code>, il n'y a pas de crash: la fonction "crashy" n'est jamais appelée à cause de l'évaluation de court-circuit.
L'évaluation de court-circuit est garantie pour l'opérateur intégré || code> et opérateur && code>, quel que soit le type de données. Vous n'obtenez pas d'évaluation de court-circuit pour un type de données défini par l'utilisateur qui surcharge B> ces opérateurs, car l'opérateur surchargé est une fonction normale et que les deux arguments doivent être transmis à cette fonction.
Dans de nombreux cas, il n'y a pas de différence pratique en dehors d'une infime d'amélioration de la performance. Lorsque cela devient utile, c'est si vos chèques sont des appels de fonction très coûteux (peu probable) ou vous devez vérifier les choses en ordre. Dis par exemple, vous voulez vérifier une propriété sur quelque chose et vérifier si quelque chose est nul tout d'abord, vous pourriez faire quelque chose comme: p>
si (a! = nil && a.attribute == valide) {} p>
Oui, c'est exactement, vous gagnez de l'heure, cela ne semblera pas grand chose pour une opération, mais vous devez garder à l'esprit que les opérations seront répétées des millions de fois p>
Pourquoi effectuer deux évaluations quand on suffit est la logique p>
Il ne s'agit pas seulement de choisir la condition la plus probable à gauche. Vous pouvez également avoir une protection sécurisée à gauche pour le sens que vous ne pouvez avoir qu'une seule commande. Considérons Vous ne pouvez pas échanger la commande ici car la première condition protège la seconde de lancer une NPE. P> De même, vous pouvez avoir P> if (s != null && s.length() > 0) // if the String is not empty
J'aimerais pouvoir uppoter cela un couple de plus - l'exactitude est une considération plus importante que "qui est plus probable" en ce qui concerne le placement de l'opérande avec les opérateurs de court-circuit. Aussi - beaux exemples du monde réel; Le second est particulièrement important pour un novice à comprendre, car c'est une idiome très courante.
au moment de l'exécution si (A || B) testera un premier, si A est vrai, il ne perdra pas le test de temps Bori le compilateur sera une exécution à l'avance. Par conséquent, si A est plus susceptible d'être vrai que B Ce test est également susceptible de couper 1 ligne. Le nombre total de lignes non exécutées est minuscule sur une seule ligne, mais elle est énorme si la déclaration est imbriquée dans une boucle d'une sorte (pour, pendant la récession ou des requêtes liées à la base de données). Par exemple, par exemple, nous avons 1 million de minutes pour tester des données dans une base de données à 1 minute par enregistrement (30 secondes pour la condition A et 30 secondes pour la condition B). Soit A 80% de chances d'être vrai et b avoir 20% de chances d'être vrai. Le temps total requis si vous mettez un premier à 600-000 heures, il est encore 900-000 heures si vous mettez B PREMIER.Si A est testé d'abord [(0,8 * 1 millions heures) * 0,5ms + (0,2 * 1 Million) * 1min] === 6000-000hrs: Si B est testé d'abord [(0,2 * 1 Million heures) * 0,5ms + (0,2 * 1 Million heures) * 1min] === 9000-000hrs. Cependant, vous remarquerez que la différence est moins importante si la probabilité de devenir vrai est plus proche de celle de b. P>
C'est court-circuit i> et déjà couvert dans l'une des réponses
public class Main
{
public static void main(String[] args) {
System.out.println("Hello World");
Integer a = null;
Integer b = 3;
Integer c = 5;
if(a != null && a == 2){
System.out.println("both");
}else{
System.out.println("false");
}
}
}
Hello World
false
N'oubliez pas que si votre état est ou placé la condition plus susceptible d'être vrai en premier, car c'est suffisant pour savoir que toute la condition sera vraie. Si votre état est un et mettez la condition qui va être faux d'abord parce que cela suffit à avoir tout votre état faux. Java vous permet également d'évaluer les deux conditions (pas courtes circuits) en utilisant '|' et des opérateurs '&'.
@gersonzaragocine - Le
| code> etet code> Les opérateurs de Java (et C et C ++) sont des opérateurs bitwises. Pour les valeurs booléennes, ils agissent comme vous le décrivez, mais ce n'est pas leur but.@Petebecker Cet opérateur dans JLS sont appelés opérateurs "Bitwise et logique". Veuillez vérifier cette section, ils sont définis à la fin docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#JLS-15 .22 . C'est un exemple clair de surcharge de l'opérateur.
@gersonzaragocin - Merci. Pour les types booléens, ils sont documentés pour effectuer des opérations logiques et fonctionnent car les valeurs booléennes sont 1 et 0; Ils font toujours des opérations bitwises. Cependant, pour d'autres types, ils ne donnent pas le même résultat que
|| code> ou `&& ', qui était mon point.