CodeGym /Blog Java /Random-FR /Déclaration de commutateur Java
Auteur
Milan Vucic
Programming Tutor at Codementor.io

Déclaration de commutateur Java

Publié dans le groupe Random-FR

Un peu de théorie sur Java Switch

Imaginez que vous êtes un chevalier arrêté à une bifurcation de la route. Si vous allez à gauche, vous perdrez votre cheval. Si vous allez à droite, vous acquerrez des connaissances. Comment représenterions-nous cette situation dans le code ? Vous savez probablement déjà que nous utilisons des constructions telles que if-then et if-then-else pour prendre ces décisions.

if (turn_left) { 
    System.out.println("You will lose your horse"); 
}
if (turn_right) {
    System.out.println("You will gain knowledge");
}
else 
    System.out.println("So you're just going to stand there?");

Mais que se passe-t-il si la route ne se divise pas en deux, mais en dix ? Vous avez des routes qui sont "complètement à droite", "un peu à gauche de ça", "un peu plus à gauche" et ainsi de suite, totalisant 10 routes possibles ? Imaginez comment votre code "if-then-else " va grandir dans cette version !

if (option1)
{…}
else if (option2)
{…}
…
else if (optionN) ...
Supposons que vous ayez une bifurcation à 10 voies sur la route (il est important ici que le nombre d'options soit fini). Pour de telles situations, Java a l' instruction switch .

       switch (ExpressionForMakingAChoice) {
           case (Value1):
               Code1;
               break;
           case (Value2):
               Code2;
               break;
...
           case (ValueN):
               CodeN;
               break;
           default:
               CodeForDefaultChoice;
               break;
       }

Voici comment fonctionne l'instruction :
  • ExpressionForMakingAChoice est évalué. Ensuite, l'instruction switch compare la valeur résultante avec la ValueX suivante (dans l'ordre dans lequel elles sont répertoriées).
  • Si ExpressionForMakingAChoice correspond à ValueX, le code suivant les deux-points est exécuté.
  • Si une instruction break est rencontrée, le contrôle est transféré en dehors de l'instruction switch.
  • Si ExpressionForMakingAChoice ne correspond à aucune ValueX, le contrôle passe à CodeForDefaultCase.
Les points importants
  • Dans l'instruction switch, le type de ExpressionForMakingAChoice doit être l'un des suivants :

    • octet , court , caractère , int .
    • Byte , Short , Character , Integer (wrappers des types de données primitifs).
    • Chaîne .
    • Enum .
  • Le bloc par défaut est facultatif. S'il est absent et que ExpressionForMakingAChoice ne correspond à aucune ValueX, aucune action ne sera exécutée.
  • L' instruction break n'est pas obligatoire. S'il est absent, le code continuera à être exécuté (en ignorant les comparaisons ultérieures dans les instructions case) jusqu'à la première occurrence de break ou jusqu'à la fin de l' instruction switch .
  • Si le même code doit être exécuté pour plusieurs choix, nous pouvons éliminer la duplication en spécifiant plusieurs instructions de cas consécutives.

Voyons maintenant comment l'instruction switch est utilisée en Java

Ne vous inquiétez pas : nous en avons fini avec la théorie. Après avoir vu les exemples suivants, tout deviendra beaucoup plus clair. Eh bien, commençons. Regardons un exemple de l'astronomie impliquant les planètes de notre système solaire. Conformément aux dernières attitudes internationales, nous avons exclu Pluton (en raison des propriétés de son orbite). Rappelons que nos planètes sont disposées selon leur distance au Soleil comme suit : Mercure, Vénus, Terre, Mars, Jupiter, Saturne, Uranus et Neptune. Écrivons une méthode Java qui prend le nombre ordinal d'une planète (relatif à sa distance par rapport au Soleil) et renvoie les principaux composants de l'atmosphère de la planète sous la forme d'une List<String>. Vous vous souviendrez que certaines planètes ont une composition atmosphérique similaire. Ainsi, Vénus et Mars contiennent principalement du dioxyde de carbone ; l'atmosphère de Jupiter et de Saturne est constituée d'hydrogène et d'hélium ; et Uranus et Neptune ajoutent du méthane à la dernière paire de gaz. Voici notre fonction :

public static List<String> getPlanetAtmosphere(int seqNumberFromSun) {
    List<String> result = new ArrayList<>();
    switch (seqNumberFromSun) {
        case 1: result.add("No atmosphere");
            break;
        case 2:
        case 4: result.add("Carbon dioxide");
            break;
        case 3: result.add("Carbon dioxide");
            result.add("Nitrogen");
            result.add ("Oxygen");
            break;
        case 5:
        case 6: result.add("Hydrogen");
            result.add("Helium");
            break;
        case 7:
        case 8: result.add("Methane");
            result.add("Hydrogen");
            result.add("Helium");
            break;
        default:
            break;
    }
    return result;
}
Notez que nous utilisons le même code pour les planètes avec des compositions atmosphériques identiques. Pour ce faire, nous avons utilisé des instructions de cas consécutives . Si nous voulons obtenir la composition de l'atmosphère de notre planète natale, nous appelons notre méthode avec 3 comme argument :

getPlanetAtmosphere(3).
System.out.println(getPlanetAtmosphere(3)) returns ["Carbon dioxide", "Nitrogen", "Oxygen"].
Expérimentez avec break : que se passe-t-il si nous supprimons toutes les instructions break ? Essayons:

    public static List<String> getPlanetAtmosphere(int seqNumberFromSun) {
        List<String> result = new ArrayList<>();
        switch (seqNumberFromSun) {
            case 1: result.add("No atmosphere");
            case 2:
            case 4: result.add("Carbon dioxide");
            case 3: result.add("Carbon dioxide");
                result.add("Nitrogen");
                result.add ("Oxygen");
            case 5:
            case 6: result.add("Hydrogen");
                result.add("Helium");
            case 7:
            case 8: result.add("Methane");
                result.add("Hydrogen");
                result.add("Helium");
            default:
        }
        return result;
    }
Si nous imprimons le résultat de System.out.println(getPlanetAtmosphere(3)) , nous constatons que notre planète natale n'est pas si vivable. Ou est-ce? Jugez par vous-même : ["Dioxyde de carbone", "Azote", "Oxygène", "Hydrogène", "Hélium", "Méthane", "Hydrogène", "Hélium"] . Pourquoi est-ce arrivé? Le programme exécute toutes les instructions case après la première correspondance jusqu'à la fin du bloc switch .

Optimisation excessive des instructions de rupture

Notez que nous pouvons améliorer la méthode en organisant différemment les instructions break et les cas.

public static List<String> getPlanetAtmosphere(int seqNumberFromSun) {
    List<String> result = new ArrayList<>();
    switch (seqNumberFromSun) {
        case 1: result.add("No atmosphere");
                break;
        case 3: result.add("Nitrogen");
                result.add ("Oxygen");
        case 2:
        case 4: result.add("Carbon dioxide");
                break;
        case 7:
        case 8: result.add("Methane");
        case 5:
        case 6: result.add("Hydrogen");
                result.add("Helium");
    }
     return result;
}
Ressemble à moins de code, non ? Nous avons réduit le nombre total d'instructions en jouant avec l'ordre des instructions de cas et en les regroupant. Désormais, chaque type de gaz est ajouté à la liste en une seule ligne de code. Le code donné dans le dernier exemple sert uniquement à montrer comment les choses fonctionnent. Nous ne recommandons pas d'écrire du code de cette façon. Si l'auteur d'un tel code Java (sans parler d'autres programmeurs) doit le maintenir, il ou elle trouvera très difficile de reconstruire la logique derrière la formation de ces blocs de cas et le code exécuté dans l'instruction switch .

Différences avec si

Étant donné les similitudes extérieures des instructions if et switch , n'oubliez pas que l' instruction switch sélectionne l'un des cas en fonction d'une VALEUR SPÉCIFIQUE, alors que l'instruction if peut avoir n'importe quelle expression booléenne. Gardez cela à l'esprit lors de la conception de votre code.

Conclusion

  • Utilisez l' instruction case pour plus de deux branches afin de ne pas encombrer votre code avec des instructions if.
  • N'oubliez pas de compléter le bloc logique de la branche pour chaque valeur spécifique (instruction case) en insérant une instruction break .
  • L' expression de l'instruction switch peut être un Enum ou String , ainsi que certains types primitifs.
  • N'oubliez pas le bloc par défaut . Utilisez-le pour gérer les valeurs inattendues.
  • Pour optimiser les performances, déplacez les branches de code correspondant aux valeurs les plus courantes au début du bloc switch .
  • Ne vous laissez pas emporter dans votre "optimisation" en supprimant les instructions break à la fin des instructions case - un tel code est difficile à comprendre et, par conséquent, difficile à maintenir.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION