Pular para o conteúdo principal

Guia da certificação Java SE 8 Programmer l - Parte 3: Operadores, decisões e loops

Seja bem-vindo a série de postagens sobre a certificação Java. Como funciona, o que fazer para comprar, marcar o dia da prova e o principal, o que estudar.

Para ver o índice da série e as datas das publicações, acesse este link


Parte 3 – Operadores, decisões e loops

Neste post, vamos dar mais um passo nos detalhes da linguagem quanto aos operadores, decisões e loops.

Objetivos do exame

  • Precedência com uso de parenteses
  • If, if/else e operadores ternários
  • Usando o switch
  • Usando while
  • Loops for
  • Do/while loops
  • Break e continue

Operadores Java

Para o exame, será preciso conhecer os operadores Java e como ela é resolvida. Nem sempre a operação será resolvida da esquerda para a direita. Ex:
int y = 8;
int x = 2 - 5 + 3 * 4 - --y;

No exemplo acima, é feita a subtração de uma unidade de y, após é feita a multiplicação e depois resolve da esquerda para a direita. O resultado a operação acima é 2.

Os operadores que aparecerão na prova são: (+), (-), (*), (/) e resto da divisão (%). Os operadores (*, / e %) tem precedência sobre os operadores (+ e -). Para dar preferência a um operador de menos precedência, utilizamos os parenteses.
int x = (2 - 5 + 3) * 4 - --y;

Agora o resultado é -7

O operador + e += pode ser aplicado também a String, resultando na concatenação. O operador resto (%) é exatamente o resto da divisão entre dois números.

System.out.println(21 / 4); //resultado = 5
System.out.println(21 % 4); //resultado = 1

Você deve lembrar que se fizer uma operação com dois tipos de números diferentes, o tipo com menos tamanho será convertido para o maior tipo. Ex:

int y = 8;
long x = 10;
int w = y + x; //erro de compilação

Se um dos valores for de ponto flutuante, o valor inteiro será promovido automaticamente para ponto flutuante. No caso dos dois valores forem de ponto flutuante, o que vale é o double.
double a = 2.2;
float b = 3.3f;
float c = a * b;//erro de compilação

Cuidado com algumas pegadinhas na prova.

Inversão de valores

int x = -14;
System.out.println(x); //print -14
x = -x;
System.out.println(x); //print 14

Qualquer valor abaixo de int que tiver uma operação matemática executada, será transformado em int.
short a = 1;
short b = 2;
short c = a + b; //erro de compilação

Porem se utilizarmos operadores de incremento e decremento (-- e ++) para atribuir a variável, é feito o cast automaticamente.(++) e (--) tem preferência aos operadores binários. Dependendo da localização do operador, o resultado da expressão pode ser diferente. Ele pode ser colocado antes ou depois da variável.

short a = 1;
short b = ++a; //ok
int x = ++b + a--; //válido
System.out.println(x); //Resultado é 5

Cast de dados primitivos

Quanto um valor literal não cabe no tipo de variável declarada, ainda é possível atribuir o valor fazendo um cast. Com o cast e possível associar um valor de ponto flutuante em um int por exemplo. Um valor maior a um short. Porém cuidado com este tipo de conversão, pois poderá haver perda de consistência. Cuidado com atribuição dentro de atribuições.
x = 1
y = (x = 3) //ok, y = 3

Operadores relacionais

Sempre retornam um valor booleano. O operador instanceof não é cobrado no exame menor que (<), menor ou igual(<=), maior que (>) e maior ou igual (>=).

Operadores lógicos

Temos três operadores lógicos: e ( & ), or inclusivo ( | ) e or exclusivo( ^ )

Operadores de curto circuito

Para este tipo de operador, a diferença é que se a expressão da direita retornar true, o restante da expressão não é avaliada. Um exemplo clássico deste uso é a verificação de uma variável.
if (a != null && a.equals("a")){
}
Caso a variável a for null, então a segunda expressão nunca será executada, evitando uma exceção. Para o exame, é possível ter uma pergunta que incrementa uma variável em uma expressão. Ex:
String a = "a";
int b = 6;
if (a != null && b++ == 7){
    System.out.println(a);
}
System.out.println(b);
O que acontece se executarmos o código acima? A variável a não será impressa, porém o valor da variável b será 7 após o if. Caso a variável a fosse null, então o valor de b seria 6. A variável b não é 7 no momento do if, pois está utilizando um operador de incremento posterior.

Comparação de igualdade (==)

É possível comparar objetos, números primitivos e valores booleanos.
System.out.println(500 == 5_0_0.0_0_0__0); //true
O exemplo acima compila e retorna true, pois o Java consegue converter o valor da esquerda para double. Para comparação de objetos, o operador de igualdade é aplicado às referências aos objetos, não os objetos para os quais eles apontam. Duas referências são iguais se e somente se apontarem para o mesmo objeto, ou ambos apontam para null.

Relação completa dos operadores Java:
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/opsummary.html

Java Statements


O controle de fluxo de um código Java é feito pelos statements, conhecidos como: if/else, if/then/else, operador ternário, switch, while, do-while e for.

If sempre deve retornar um booleano, porém podemos ter atribuições de variáveis ou incremento de valores dentro da expressão. Então muito cuidado ao analisar questões como esta:
int x = 1;
if (++x > 1)
System.out.println("x is greater than one!");
No código acima, teremos a impressão da mensagem pois a variável x foi incrementada antes da verificação da condição. E também como tínhamos apenas uma instrução dentro do if, não precisamos das chaves. Na prova pode ocorrer que o código não esteja identado e te induza ao erro.
int x = 1;
if (x++ > 1)
    System.out.println("x is greater than one!");
    System.out.println("x is " + x);
No código acima, você poderá ser questionado sobre a saída da execução. Olhe com cuidado, pois o if não possui abertura de chaves, então somente a primeira linha após o if seria executada caso a expressão retornasse true. O que não é o caso. Como o x é incrementado depois, ele não será maior que 2. Porém o segundo print não esta dentro do if e a saída da execução será 2.
Para o if/else, a regra é a mesma. Caso tenha apenas uma instrução apos o if, não é necessário as chaves.
int x = 1;
if (x++ > 1)
    System.out.println("x is greater than one!");
else
    System.out.println("x is not greater than one");
    System.out.println("x is " + x);
Neste outro código, o último System.out sempre será executado independente do resultado da expressão. Uma vez executado o código abaixo da expressão verdadeira, os demais ifs serão ignorados. Então a ordem dos ifs é importante.
int hourOfDay = 10;
if(hourOfDay < 15) {
    System.out.println("Good Afternoon");
} else if(hourOfDay < 11) {
    System.out.println("Good Morning"); // nunca será executado
} else {
    System.out.println("Good Evening");
}
Sempre verifique se a expressão esta verificando uma condição booleana. O código abaixo não compila, pois esta sendo feita uma atribuição dentro do if.
int age = 18;
if(age = 18)
    System.out.println("Major!"); //não compila

Operador ternário

Um dos operadores que mais pode causar confusão no momento da prova. O operador é relativamente simples, porém se ele aparecer de forma encadeada, ai fica difícil e demorado para verificar o resultado. Pense no operador ternário como um if/then/else.
if ? then : else
int x = 1;
int y = x > 1 ? 10 : 20;
O código acima seria o mesmo que:
int x = 1;
int y;
if (x > 1) {
    y = 10;
} else {
    y = 20;
}
Agora um exemplo que talvez você encontre na prova:
int x = 1;
int y = x >= 1 ? x == 1 ? 2 : 3 : 20;
Se o x for maior ou igual a 1, então ele avalia outra expressão. Se o x for igual a 1, então retorna 2, senão retorna 3;

Switch

A partir do Java 7, a String também foi incorporada no switch. Os tipos de dados suportados são:
■ int e Integer
■ byte e Byte
■ short e Short
■ char e Character
■ int e Integer
■ String
■ enum

Somente os tipos acima são permitidos. Não tente utilizar um double ou long por exemplo. Você terá um erro de compilação. No caso do switch, sempre devemos utilizar o break para que o fluxo siga para fora do switch, pois caso não utilizar, o Java continua verificando as condições.
int age = 1;
switch(age) {
    default:
        System.out.println("default");
    case 2:
        System.out.println("two years old");
    case 3:
        System.out.println("three years old");
}
O que acontece ao executar o bloco de código acima? Por mais que nenhuma condição seja atendida explicitamente, foi utilizado o default que será executado quando nenhuma condição for verdadeira. E como não foi utilizada a instrução break, todas as condições abaixo serão executadas.

Todo valor da expressão case deve ser uma constante e do mesmo tipo da expressão switch. Pode ser um literal, um enum, uma variável final.
String var = "test1";
final String var1 = "test2";
switch (args[0]) {
    case "test":
        System.out.println("test");
    case var: //erro de compilação
        System.out.println("test1");
    case var1:
        System.out.println("test2");
}

While

Um while é parecido com o if, porém a instrução dentro do while é executada enquanto a condição for verdadeira.
int x = 0;
while (x++ < 10)
    System.out.println(x);
Assim como o if, não é obrigatório ter a abertura de chaves. Neste caso o print será executado 10 vezes e então continuar o fluxo. Caso o x não fosse incrementado dentro do while, então teríamos um loop infinito. Seria a mesma coisa que fazer um while (true).

Do while

A diferença para o while é que o do/while será executado pelo menos uma vez antes de verificar a expressão booleana.

Comando for

O comando for é um pouco mais complexo que o while e o do/while. Ele tem duas formas. A primeira chamada de forma básica existente desde o Java 1. A partir do Java 5, temos o for-each. O for básico possui três blocos (inicialização; expressão booleana; incremento) e todos eles são opcionais. Temos apenas como obrigação separar com ponto e virgula.
for (; ; )
    System.out.println("infinite loop!");
A instrução acima é válida e faz um loop infinito devido ao não controle do fluxo. Podemos utilizar múltiplas instruções nos blocos do for. Inicializando varias variáveis, verificando expressões booleanas e incrementando algumas variáveis.
for (int x = 0, y = 0; x <= 10 && y <= 10 ; x++, y++){
    System.out.println(x);
    System.out.println(y);
}
No exemplo acima, estamos inicializando duas variáveis, comparando os valores e incrementado. Esse tipo de questão é bem comum na prova, então pratique bastante. Não é possível redeclarar uma variável dentro do for. Ex:
public static void main(String[] args) {
    int y = 1;
    for (int x = 0, y = 0; x <= 10 && y <= 10 ; x++, y++){ //erro
}
Para o código acima compilar, basta retirar a declaração as variáveis de dentro do for e passar para fora do for. Outro detalhe é que não é possível declarar tipos diferentes no bloco de inicialização. E lembre-se, caso a variável tenha sido declarada no bloco de inicialização do for, ela é de escopo local do for e não pode ser utilizada fora dele.

For-each

O for-each foi introduzido na versão 5 do Java e para o exame é preciso reconhecer uma iteração utilizando o List e ArrayList:
List<String> names = Arrays.asList("Sara", "Lisa", "Andrew");
for (String name : names) {
    System.out.println(name);
}
O for é divido em dois blocos. O primeiro é a declaração do objeto que esta dentro da coleção. No caso, para uma lista de Strings é declarado apenas o objeto String. Separamos o bloco de inicialização do bloco da lista a ser iterada por dois pontos.

Controle de fluxo avançado

Loops podem conter outros loops, então as coisas podem ficar um pouco mais complicadas no exame. O que é bem comum.
int[][] matrix = {{4, 3, 2, 1}, {3, 4, 5, 6, 3}, {2, 3, 4, 5, 6, 7}};
for (int[] ints : matrix) {
    for (int i = 0; i < ints.length; i++) {
        System.out.print(ints[i] + "\t");
    }
    System.out.println();
}
Dentro destes loops ainda é possível que tenha uma lógica e você deve acertar o resultado de saída.
int x = 0, y = 2;
while (x < 5) {
    x++;
    do {
        y++;
    } while (y < 10);
}
System.out.println(x);
System.out.println(y);
Qual o resultado de x e y apos a execução do código acima?

break e continue

A diferença entre o break e o continue é que o break irá terminal o fluxo do loop atual e continuará para fora do loop e o continue interromperá o loop atual e retornará para a validação booleana se deve continuar com o loop. Existem ainda os labels, porém não são cobrados na prova.

Para saber mais:
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html

Conclusão

O tópico de controle de fluxo e repetição sem dúvida é um dos mais importantes do exame, pois a maioria dos exemplos de código terão algum if ou loop. Ocasionalmente a pergunta pode ser de um determinado assunto, porém a resposta pode ser um erro de compilação devido ao if, for ou loop que não compila.

Bons estudos e até a próxima!









Comentários

Postagens mais visitadas deste blog

Certificação Java 11 - O que mudou

Certificação Java 11 - O que mudou A Oracle liberou recentemente uma atualização das suas certificações Java para atender a nova versão Java 11  LTS (Long Term Support) . Mas o que muda em relação a certificação Java 8? Preciso me atualizar? Por onde começo?  Neste post, vamos responder estas e outras questões sobre essa nova série de certificações. Caso você não tenha acompanhado a série sobre certificação, recomendo a leitura dos posts anteriores: https://www.guiadojava.com.br/2018/06/guia-da-certificacao-java-se-8.html Também temos um bate papo com os maiores especialistas de Java do mercado. Assista o replay aqui: https://events.genndi.com/replay/169105139238448348/23a5b3a7b0/0/83729443273C Nomenclatura e requisitos A partir de agora, você não receberá o certificado se fizer apenas a primeira prova, como era no Java 8 (1Z0-808 - Java SE 8 Programmer I). Você terá que fazer duas provas para obter o certificado " Oracle Certified Professional: Java SE 11 Dev

Java 15 - Novidades (ou não)

Java 15 - Novidades (ou não) O Java 15 já está em fase de testes com as suas features fechadas (Rampdown Phase One). Isso quer dizer que mais nenhuma feature será implementada. Teremos melhorias em funcionalidades já liberadas para testes e outras consolidadas agora nesta versão, mas nada de grandes mudanças. Porém é sempre bom ficar atualizado não é? Para acompanhar os builds e agenda da liberação, acesse esta página . Revisando o processo de versionamento Com o lançamento do  Java 9 em 2017 , o cronograma de lançamento do Java mudou, de um lançamento principal a cada  3 anos ou mais  para um lançamento a cada  seis meses . Um dos principais motivos dessa alteração foi oferecer aos desenvolvedores acesso mais rápido as melhorias contínuas. Os lançamentos ocorrem em  Março  e  Setembro  de cada ano. Ainda cabe um post específico para o modelo de versionamento para explicar sobre as versões LTS, versões intermediárias e funcionalidades " preview ". Para mais informações, veja

Guia da certificação Java SE 8 Programmer l - Parte 1: Conhecendo a certificação

Seja bem-vindo a série de postagens sobre a certificação Java. Como funciona, o que fazer para comprar, marcar o dia da prova e o principal, o que estudar. Para ver o índice da série e as datas das publicações, acesse este link Parte 1 – Conhecendo a certificação Nesta primeira parte, vamos navegar pelo site da Oracle Education e da Pearson VUE para conhecer como funciona a certificação e se ambientar. Ambos os site estão em Inglês e como já dito no índice da série, a prova não tem opção em português. Site da Oracle O site da Oracle não é um dos melhores em usabilidade. Então se procurar por certificação Java no Google, irá encontrar diversos cursos, livros e blogs falando a respeito da certificação menos o site da Oracle. Pois bem, abaixo o link direto para informações do exame 1Z0-808 - Java SE 8 Programmer I https://education.oracle.com/pls/web_prod-plq-dad/db_pages.getpage?page_id=5001&get_params=p_exam_id:1Z0-808 Neste link você encontrará