CodeGym /Blogue Java /Random-PT /Instrução Java switch
John Squirrels
Nível 41
San Francisco

Instrução Java switch

Publicado no grupo Random-PT

Um pouco de teoria sobre o Java Switch

Imagine que você é um cavaleiro parado em uma bifurcação na estrada. Se você for para a esquerda, perderá seu cavalo. Se você for certo, você ganhará conhecimento. Como representaríamos essa situação em código? Você provavelmente já sabe que usamos construções como if-then e if-then-else para tomar essas decisões.

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

Mas e se a estrada se dividir não em duas, mas em dez? Você tem estradas que estão "totalmente à direita", "um pouco à esquerda disso", "um pouco mais à esquerda" e assim por diante, totalizando 10 estradas possíveis? Imagine como seu código "if-then-else " crescerá nesta versão!

if (option1)
{…}
else if (option2)
{…}
…
else if (optionN) ...
Suponha que você tenha uma bifurcação de 10 vias na estrada (é importante aqui que o número de opções seja finito). Para tais situações, Java tem a instrução switch .

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

A declaração funciona assim:
  • ExpressionForMakingAChoice é avaliado. Em seguida, a instrução switch compara o valor resultante com o próximo ValueX (na ordem em que estão listados).
  • Se ExpressionForMakingAChoice corresponder a ValueX, o código após os dois pontos será executado.
  • Se uma instrução break for encontrada, o controle será transferido para fora da instrução switch.
  • Se ExpressionForMakingAChoice não corresponder a nenhum ValueX, o controle passará para CodeForDefaultCase.
Pontos importantes
  • Na instrução switch, o tipo de ExpressionForMakingAChoice deve ser um dos seguintes:

    • byte , curto , char , int .
    • Byte , Short , Character , Integer (invólucros dos tipos de dados primitivos).
    • Corda .
    • Enum .
  • O bloco padrão é opcional. Se estiver ausente e ExpressionForMakingAChoice não corresponder a nenhum ValueX, nenhuma ação será executada.
  • A instrução break não é necessária. Se estiver ausente, o código continuará a ser executado (ignorando outras comparações nas instruções case) até a primeira ocorrência de break ou até o final da instrução switch .
  • Se o mesmo código precisar ser executado para várias opções, podemos eliminar a duplicação especificando várias instruções case consecutivas.

Vamos agora dar uma olhada em como a instrução switch é usada em Java

Não se preocupe: acabamos com a teoria. Depois de ver os exemplos a seguir, tudo ficará muito mais claro. Bem, vamos começar. Vejamos um exemplo da astronomia envolvendo os planetas do nosso sistema solar. De acordo com as últimas atitudes internacionais, excluímos Plutão (devido às propriedades de sua órbita). Lembramos que nossos planetas estão dispostos por sua distância ao Sol da seguinte forma: Mercúrio, Vênus, Terra, Marte, Júpiter, Saturno, Urano e Netuno. Vamos escrever um método Java que pega o número ordinal de um planeta (relativo à sua distância do Sol) e retorna os principais componentes da atmosfera do planeta como uma List<String>. Você deve se lembrar que alguns planetas têm uma composição atmosférica semelhante. Assim, Vênus e Marte contêm principalmente dióxido de carbono; a atmosfera de Júpiter e Saturno consiste em hidrogênio e hélio; e Urano e Netuno adicionam metano ao último par de gases. Aqui está a nossa função:

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;
}
Observe que estamos usando o mesmo código para planetas com composições atmosféricas idênticas. Fizemos isso usando declarações case consecutivas . Se quisermos obter a composição da atmosfera do nosso planeta natal, chamamos nosso método com 3 como argumento:

getPlanetAtmosphere(3).
System.out.println(getPlanetAtmosphere(3)) returns ["Carbon dioxide", "Nitrogen", "Oxygen"].
Experimente com break: O que acontece se removermos todas as instruções break ? Vamos tentar:

    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;
    }
Se imprimirmos o resultado de System.out.println(getPlanetAtmosphere(3)) , descobriremos que nosso planeta natal não é tão habitável. Ou é? Julgue por si mesmo: ["Dióxido de carbono", "Nitrogênio", "Oxigênio", "Hidrogênio", "Hélio", "Metano", "Hidrogênio", "Hélio"] . Por quê isso aconteceu? O programa executa todas as instruções case após a primeira correspondência até o final do bloco switch .

Otimização excessiva de instruções break

Observe que podemos melhorar o método organizando as instruções break e cases de maneira 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, certo? Reduzimos o número total de instruções brincando com a ordem das instruções de caso e reagrupando-as. Agora cada tipo de gás é adicionado à lista em apenas uma linha de código. O código dado no último exemplo é apenas para mostrar como as coisas funcionam. Não recomendamos escrever código dessa maneira. Se o autor desse código Java (para não falar de outros programadores) precisar mantê-lo, ele ou ela achará muito difícil reconstruir a lógica por trás da formação desses blocos case e do código executado na instrução switch .

Diferenças de se

Dadas as semelhanças externas das instruções if e switch , não se esqueça de que a instrução switch seleciona um dos casos com base em um VALOR ESPECÍFICO, enquanto a instrução if pode ter qualquer expressão booleana. Tenha isso em mente ao projetar seu código.

Conclusão

  • Use a instrução case para mais de duas ramificações para não sobrecarregar seu código com instruções if.
  • Não se esqueça de completar o bloco lógico da ramificação para cada valor específico (instrução case) inserindo uma instrução break .
  • A expressão da instrução switch pode ser um Enum ou String , bem como alguns tipos primitivos.
  • Lembre-se do bloco padrão . Use-o para lidar com valores inesperados.
  • Para otimizar o desempenho, mova as ramificações de código correspondentes aos valores mais comuns para o início do bloco switch .
  • Não se empolgue em sua "otimização" excluindo as instruções break no final das instruções case – esse código é difícil de entender e, como resultado, difícil de manter.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION