CodeGym /Blog Java /Random-ES /Declaración de cambio de Java
Autor
Milan Vucic
Programming Tutor at Codementor.io

Declaración de cambio de Java

Publicado en el grupo Random-ES

Un poco de teoría sobre Java Switch

Imagina que eres un caballero detenido en una bifurcación del camino. Si vas a la izquierda, perderás tu caballo. Si vas bien, obtendrás conocimiento. ¿Cómo representaríamos esta situación en código? Probablemente ya sepa que usamos construcciones como if-then y if-then-else para tomar estas decisiones.

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?");

Pero, ¿y si el camino no se divide en dos, sino en diez? ¿Tiene caminos que están "totalmente a la derecha", "ligeramente a la izquierda de eso", "un poco más a la izquierda" y así sucesivamente, totalizando 10 caminos posibles? ¡Imagínate cómo crecerá tu código "if-then-else " en esta versión!

if (option1)
{…}
else if (option2)
{…}
…
else if (optionN) ...
Suponga que tiene una bifurcación de 10 vías en el camino (aquí es importante que el número de opciones sea finito). Para tales situaciones, Java tiene la instrucción switch .

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

Así es como funciona la declaración:
  • Se evalúa ExpressionForMakingAChoice. Luego, la declaración de cambio compara el valor resultante con el siguiente ValueX (en el orden en que se enumeran).
  • Si ExpressionForMakingAChoice coincide con ValueX, se ejecuta el código que sigue a los dos puntos.
  • Si se encuentra una sentencia break , el control se transfiere fuera de la sentencia switch.
  • Si ExpressionForMakingAChoice no coincide con ningún ValueX, el control pasa a CodeForDefaultCase.
Puntos importantes
  • En la declaración de cambio, el tipo de ExpressionForMakingAChoice debe ser uno de los siguientes:

    • byte , corto , char , int .
    • Byte , Short , Character , Integer (envolturas de los tipos de datos primitivos).
    • Cuerda .
    • enumeración _
  • El bloque predeterminado es opcional. Si está ausente y ExpressionForMakingAChoice no coincide con ningún ValueX, no se ejecutará ninguna acción.
  • La instrucción break no es necesaria. Si está ausente, el código seguirá ejecutándose (ignorando más comparaciones en las sentencias case) hasta la primera aparición de break o hasta el final de la sentencia switch .
  • Si se necesita ejecutar el mismo código para varias opciones, podemos eliminar la duplicación especificando varias declaraciones de casos consecutivas .

Ahora echemos un vistazo a cómo se usa la instrucción switch en Java

No te preocupes: hemos terminado con la teoría. Después de ver los siguientes ejemplos, todo se volverá mucho más claro. Bueno, comencemos. Veamos un ejemplo de la astronomía que involucra a los planetas de nuestro sistema solar. De acuerdo con las últimas actitudes internacionales, hemos excluido a Plutón (debido a las propiedades de su órbita). Recordamos que nuestros planetas están ordenados por su distancia al Sol de la siguiente manera: Mercurio, Venus, Tierra, Marte, Júpiter, Saturno, Urano y Neptuno. Escribamos un método Java que tome el número ordinal de un planeta (relativo a su distancia del Sol) y devuelva los principales componentes de la atmósfera del planeta como una Lista<String>. Recordarás que algunos planetas tienen una composición atmosférica similar. Así, Venus y Marte contienen principalmente dióxido de carbono; la atmósfera de Júpiter y Saturno se compone de hidrógeno y helio; y Urano y Neptuno agregan metano al último par de gases. Aquí está nuestra función:

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;
}
Tenga en cuenta que estamos usando el mismo código para planetas con composiciones atmosféricas idénticas. Hicimos esto usando declaraciones de casos consecutivos . Si queremos obtener la composición de la atmósfera de nuestro planeta de origen, llamamos a nuestro método con 3 como argumento:

getPlanetAtmosphere(3).
System.out.println(getPlanetAtmosphere(3)) returns ["Carbon dioxide", "Nitrogen", "Oxygen"].
Experimente con break: ¿Qué sucede si eliminamos todas las sentencias break ? Hagamos un intento:

    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 imprimimos el resultado de System.out.println(getPlanetAtmosphere(3)) , encontramos que nuestro planeta de origen no es tan habitable. ¿O es eso? Juzgue usted mismo: ["Dióxido de carbono", "Nitrógeno", "Oxígeno", "Hidrógeno", "Helio", "Metano", "Hidrógeno", "Helio"] . ¿Por qué pasó esto? El programa ejecuta todas las declaraciones de casos después de la primera coincidencia hasta el final del bloque de cambio .

Optimización excesiva de declaraciones de ruptura

Tenga en cuenta que podemos mejorar el método organizando las declaraciones de ruptura y los casos de manera diferente.

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;
}
Parece menos código, ¿verdad? Hemos reducido el número total de declaraciones jugando con el orden de las declaraciones de caso y reagrupándolas. Ahora cada tipo de gas se agrega a la lista en una sola línea de código. El código dado en el último ejemplo es solo para mostrar cómo funcionan las cosas. No recomendamos escribir código de esta manera. Si el autor de dicho código Java (por no hablar de otros programadores) debe mantenerlo, le resultará muy difícil reconstruir la lógica detrás de la formación de esos bloques de casos y el código ejecutado en la sentencia switch .

Diferencias de si

Dadas las similitudes externas de las sentencias if y switch , no olvide que la sentencia switch selecciona uno de los casos en función de un VALOR ESPECÍFICO, mientras que la sentencia if puede tener cualquier expresión booleana. Tenga esto en cuenta al diseñar su código.

Conclusión

  • Use la instrucción case para más de dos ramas para no saturar su código con declaraciones if.
  • No olvide completar el bloque lógico de la rama para cada valor específico (instrucción de caso) insertando una instrucción de ruptura .
  • La expresión de la sentencia switch puede ser Enum o String , así como algunos tipos primitivos.
  • Recuerde el bloque predeterminado . Úselo para manejar valores inesperados.
  • Para optimizar el rendimiento, mueva las ramas de código correspondientes a los valores más comunes al comienzo del bloque de cambio .
  • No se deje llevar por su "optimización" eliminando las declaraciones de ruptura al final de las declaraciones de caso : dicho código es difícil de entender y, como resultado, difícil de mantener.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION