Par exemple, comme ceci.
while (input != 0) { input = kb.nextInt(); ...code here...
au lieu de vérifier uniquement la valeur de la variable d'entrée à l'intérieur de la condition et d'obtenir le numéro du Scanner à l'intérieur de la boucle, comme ceci:
while ((input = kb.nextInt()) != 0) { if (input % 2 == 0) { System.out.println("even"); } else { System.out.println("odd"); }
Je me demande simplement si le premier est une mauvaise pratique ou quelque chose du genre.
3 Réponses :
Le second n'a pas l'entrée définie pour tester la condition input! = 0
donc le premier est correct, mais si vous allez utiliser le deuxième format, je suggère de changez la boucle while
en boucle do-while
.
Vos deux exemples de code ne sont pas équivalents et font des choses différentes (la deuxième version ne fait probablement pas ce que vous voulez qu'elle fasse).
Vous auriez besoin d'un autre if (input! = 0)
à l'intérieur de la boucle et l'affectation de input
avant la boucle pour la deuxième version. Déplacer l'affectation à la fin et la dupliquer avant la boucle est également une option viable:
input = kb.nextInt(); while (input != 0) { if (input % 2 == 0) { System.out.println("even"); } else { System.out.println("odd"); } input = kb.nextInt(); }
Et la première et la dernière ligne dupliquées dans cette version sont très probablement la raison du code quelque peu compliqué. Ce type de boucle loop ((x = input ())! = 0)
peut être vu dans beaucoup de code C mais est parfois «obligatoire» en Java aussi lorsque vous voulez réduire la duplication de code lors du traitement de l'entrée. Cela est dû au fait que nextInt
renvoie une valeur et modifie l'état sous-jacent.
L'utilisation de nextInt ()
dans le cadre d'une condition de boucle, bien que parfaitement légale, peut être problématique du point de vue du traitement des erreurs résultant d'une mauvaise saisie . Les humains réels assis devant un clavier saisissant des données (dont le nom de variable Scanner
kb
semble suggérer est exactement ce à quoi vous avez affaire ici) sont notoirement peu fiables en termes de leur qualité d'entrée de données, vous devez donc vous préparer à une mauvaise saisie .
nextInt ()
lèvera une exception InputMismatchException
si le La prochaine entrée disponible n'est pas une représentation valide d'un entier. Afin d'attraper et de gérer cette exception, l'appel nextInt ()
doit être exécuté à l'intérieur d'un bloc try
. Cependant, avec le nextInt ()
faisant partie de la condition de contrôle de la boucle while
, la seule façon de le faire est d'englober la boucle entière dans le try
block:
for(;;) { if (!kb.hasNextInt()) { String junk = kb.next(); System.out.println("Didn't understand your input: " + junk); System.out.println("Please type a valid integer"); } else { input = kb.nextInt(); if (input == 0) { break; else { ... } } }
Malheureusement, cela signifie que toute exception déclenchée par nextInt ()
tuera le while code > boucle. Si vous souhaitez continuer à traiter les entrées utilisateur après une erreur de saisie, vous devez fournir un moyen de relancer la boucle
while
, et continuer à la recommencer jusqu'à la "vraie" fin signalée par l'utilisateur la condition -of-input a été atteinte. Vous pourriez être en mesure de le faire avec une solution de contournement maladroite comme celle-ci:
do { try { input = kb.next(); if (input != 0) { ... } } catch (InputMismatchedException ime) { String junk = kb.next(); System.out.println("Didn't understand your input: " + junk); System.out.println("Please type a valid integer"); } } while (input != 0);
Mais en fonction de ce que le ... code> code à l'intérieur de la boucle faisait, cette solution de contournement relativement simple pourrait être inadéquate; vous pourriez avoir besoin de quelque chose d'encore plus compliqué et illisible.
Mais en déplaçant l'appel nextInt ()
hors de la logique de contrôle de la boucle et dans le corps de la boucle, vous gagnez une flexibilité considérable en termes de vos options de récupération après une mauvaise entrée. Avec nextInt ()
dans le corps de la boucle, vous pouvez désormais intercepter et gérer toute exception entièrement en une seule itération de la boucle, sans avoir à terminer la boucle elle-même:
boolean keepGoing = true; while (keepGoing){ try { while ((input = kb.nextInt()) != 0) { ... } keepGoing = false; } catch (InputMismatchException ime) { String junk = kb.next(); System.out.println("Didn't understand your input: " + junk); System.out.println("Please type a valid integer"); } }
J'ai vu les deux s'habituer. Bien que j'aime mieux le second. J'aime garder la condition à l'intérieur de la boucle while simple. Il devrait être très clair quand cette boucle se terminera pour une meilleure lisibilité.
Eh bien, la deuxième approche serait plus lisible, maintenable et testable que la première et c'est ce que disent les principes du code propre: "Gardez-le simple, lisible, maintenable et testable". Vous devez donc appliquer le second au premier