Ao
longo dessas 6 aulas fizemos um apanhado geral sobre conceitos iniciais
da linguagem Java e como explorar a característica da Abstração. A
partir de agora avançaremos no conteúdo da API de programação básica,
tratando em paralelo dos conceitos pregados pelo Encapsulamento. Nessa
aula, especificamente, falaremos apenas das estruturas de condição e
repetição que a linguagem Java nos oferece. Vamos lá!
Comentários no código Java
Os
comentários são utilizados para que o programador inclua anotações nos
códigos fontes e, no caso específico do Java, até mesmo observações que
podem ser exportadas automaticamente para a documentação de um sistema -
mais conhecida na noite carioca como API. O Java utiliza um recurso
chamado Javadoc para gerar documentação a partir de certos comentários
no código. Não vamos conversar sobre isso agora - quando falarmos de
anotações, voltaremos a abordar o assunto.
O
que devemos nos preocupara agora é: como podemos inserir comentários
num código Java? Existem dois formatos: comentários de uma linha e
comentários de várias linhas.
Para definir
comentários em uma única linha do código, basta utilizar duas barras.
Já o comentário de várias linhas deve ser obrigatoriamente inicializado
com /* e finalizado com */, podendo, se conveniente, preservar outros
asteriscos dentro do trecho comentado (fica mais elegante e de fácil
visualização).
Vejamos abaixo um exemplo.
// O comentário em Java pode ser definido com duas barras.
/*
Ou ainda com barra e asterisco, sendo que neste caso,
podem ocupar mais de uma linha.
*/
/*
* Agora ocupando mais de uma linha, porém,
* com asteriscos no início de cada linha.
*/
Existem
essas duas formas de comentários. Use e abuse dos comentários para que
os outros programadores tornem-se seus amigos no futuro! Faça um código
feioso e sem comentários e você será excluído da turma. Às vezes até
sofrerá bullying.
![]() | ![]() |
Ele inseriu comentários no programa!
|
Esse disse que não precisa, pois ele lembra tudo de cabeça!
|
Comandos de AND e OR (e revisão do IF)
A
sintaxe do Java foi inspirada no C/C++. Dessa forma comandos básicos,
como estruturas condicionais, incrementais, etc, são exatamente iguais.
Seguindo essa mesma linha nós temos os comandos AND e OR.
O AND no Java é representado por dois ê’s comerciais: &&
Já o OR, são dois pipes: ||
Para
utilizarmos esses comandos, precisamos alocá-los dentro de alguma
estrutura de decisão que a linguagem nos ofereça. Primeiro vamos
colocá-los na estrutura de condição IF. O comando IF é muito simples e
já utilizamos ele nos exercícios anteriores. Não vamos abordá-lo
novamente aqui, mas deixarei um pequeno exemplo abaixo.
int a = 0;
if ( a > 0 ) {
} else {
}
Nesse caso, como a vale zero, o trecho executado será aquele dentro das chaves do else. Vamos agora acrescentar os comandos && e || numa condição IF.
int a = 1;
int b = 2;
/*
A estrutura lógica AND no Java é expresso com &&
*/
if ( a > 0 && b > 0 ) {
System.out.println( "Eu vou entrar aqui!" );
} else {
System.out.println( "Eu NÃO vou entrar aqui!" );
}
/*
A estrutura lógica OR no Java é expresso com ||
*/
if ( a > 5 || b > 5 ) {
System.out.println( "Eu NÃO vou entrar aqui!" );
} else {
System.out.println( "Eu vou entrar aqui!" );
}
Os
comandos System.out.println(), caso ainda não tenhamos conversado, são
aqueles necessários para imprimir um texto no prompt. Nos exercícios das
aulas anteriores sempre utilizamos o método estático escrever() da classe Util - que também foi disponibilizada. Como já estamos avançando com a matéria, aos poucos vamos mostrando esses comandos.
O que interessa para nós aqui é que, na perspectiva do exemplo anterior, onde a variável a vale 1 e b vale 2, a primeira estrutura de condição cairá no bloco do IF (pois a AND b são
maiores que zero). Lembre-se que para o resultado final de um AND seja
verdadeiro, todos os elementos agrupados por ele precisam ser
verdadeiros. Nesse último exemplo, se apenas uma das variáveis não fosse
maior que zero já estaríamos fadados a executar o escopo do ELSE.
No
segundo trecho de código (onde usamos o ||), como nenhuma das opções é
verdadeira, ele cairá no trecho do ELSE. Só para reforçar, no OR, a
existência de um elemento verdadeiro agrupado pelo || já é suficiente
para que o escopo do IF seja executado. Nesse caso, como a e b não são maiores que 5, o programa executará o trecho do ELSE.
A estrutura de condição Switch/Case
Srs,
switch é uma estrutura de condição que viabiliza a comparação de
condições a vários valores possíveis, ao invés de uma variação SE/SENÃO
encontrada na estrutura IF comum.

Não vá com tanta sede ao pote! O switch só permite o uso de variáveis dos tipos primitivos byte, short, char ou int. Até tem umas gambiarras por ai (http://www.guj.com.br/java/71325-switch-com-string-faz) que
permitem o uso de Strings, por exemplo, mas não fica uma solução
elegante. Um adendo seria dizer que a partir do Java 1.5 também foi
permitido o uso de Enum no Switch. Como não vimos Enum ainda, voltaremos a falar sobre o assunto na ocasião.
Vamos então a um pequeno exemplo.
/*
Podemos utilizar o comando Switch/Case para condições
com mais de uma possibilidade. O Switch trabalha apenas
com tipos primitivos byte, short, char, ou int.
Caso não entre em nenhuma das opções, o Switch entrará
na opção default.
*/
char c = 'y';
switch ( c ) {
case 'x': System.out.println( "Valor X" ); break;
case 'y': {
System.out.println( "Valor Y" );
} break;
case 'z': System.out.println( "Valor Z" ); break;
default: System.out.println( "Outras letras..." ); break;
}
Observe a estrutura da sintaxe do switch. A variável indicada entre os parênteses do comando switch servirá como elemento de comparação para todos os case’s expostos entre as chaves. Veja que cada case só possui uma única situação. Variações de case para
> (maior que), < (menor que), >= (maior ou igual), etc, NÃO
são possíveis. O programador precisará identificar todas as situações
possíveis que a variável poderá assumir.
Eventualmente pode-se ainda optar em utilizar o comando default como último elemento da estrutura Switch/Case.
O trecho desse comando será executado quando o valor da variável não
coincidir com nenhuma das possibilidades relacionadas acima.
Note ainda que variamos o uso de chaves entre as opções cases. Isso é perfeitamente possível, somente lembrando que caso seja optado em não utilizar as chaves para o escopo de um case específico (ou até mesmo do default), só poderemos indicar um comando. No trecho case 'x': System.out.println( "Valor X" ); break; nós usamos exatamente esse formato - onde um único comando foi incluído.

Por fim, mas não menos importante, devemos nos atentar ao comando break incluído no final de cada uma das opções do Switch/Case. Esse comando diz ao Java o seguinte: Logo depois que você executar esse trecho, PARE e saia fora do SWITCH!
Isso significa que, caso não usemos o break, o fluxo de execução será iniciado na primeira condição válida com o valor da variável e em todas as condições abaixo dela.
Em outras palavras, sempre que uma das opções for selecionada (quando a condição do case conferir
com o valor da variável), o Java iniciará a execução do comando(s)
indicado na condição. Ao final desse comando(s), todavia, o fluxo
natural do Switch/Case faria com que todos os itens abaixo dele fossem
executados - mesmo que nenhuma das condições atenda ao valor da
variável.

Nesse exemplo acima, obviamente o trecho da condição case ‘x’ não é executado pois o valor da variável c é y. Já o segundo comando, case ‘y’ retém o fluxo de execução nele devido ao fato da condição ser satisfeita (o valor de c é igual a y). Todavia, como não existe o comando break no
final das chaves desse trecho, todos os demais comandos do Switch serão
executados - e veja que em nenhum deles a condição é satisfeita.
O uso do break é justamente para impedir que as demais condições, abaixo da case selecionada, sejam automaticamente executadas. O break fará com que o Java pule todas as demais condições e volte ao fluxo de execução após o fechamento da chave do switch.

Vejamos abaixo um exemplo do uso do Switch sem o break.
/*
O comando break evita a continuação dos casos quando
uma das opções é selecionada. Neste exemplo, logo
que selecionada a opção 2, todas as opções abaixo
serão selecionadas, inclusive a default.
*/
short d = 2;
switch ( d ) {
case 1: System.out.println( "Valor 1" );
case 2: System.out.println( "Valor 2" );
case 3: System.out.println( "Valor 3" );
default: System.out.println( "Outros valores" );
}
Note que o default também será executado.

Outro
detalhe importante é que o Switch não pode comportar duas condições
iguais em dois cases. Ou seja, o trecho de código abaixo vai gerar um
erro de compilação.
switch ( c ) {
case 'x': System.out.println( "Valor X" ); break;
case 'x': System.out.println( "Valor X" ); break;
case 'z': System.out.println( "Valor Z" ); break;
}

O erro ocorre porque dois cases apresentam o mesmo termo para comparação - no caso, ‘x’. A linha 43 aponta para o segundo case, que repete uma opção já utilizada anteriormente.
Então,
resumindo, o uso do case proporciona uma vantagem para o programador
que estiver usando esses tipos primitivos de varáveis, evitando o uso de
um ninho de IFs para expressar todas as possíveis condições.

Ao invés do uso dos comandos abaixo:
int temp = 1;
if ( temp == 0 ) {
// ...
} else {
if ( temp == 1 ) {
// ...
} else {
if ( temp == 2 ) {
// ...
} else {
// ...
}
}
}
Podemos utilizar a sintaxe pelo Switch.
int temp = 1;
switch ( temp ) {
case 0: {} break;
case 1: {} break;
case 2: {} break;
default: {} break;
}
Dessa forma a mesma lógica de programação fica mais enxuta - digamos assim.

Veja
bem! A literatura e os bons costumes da programação orientada a objetos
diz que o uso de switch no código, na grande maioria das vezes, indica
problemas na modelagem do projeto. Em outras palavras, o Switch é
bonitinho mas ordinario! Veja um texto que cita Martin Fowler (um guru
do Java) comentando o uso de Switch/Case: http://www.c2.com/cgi/wiki?SwitchStatementsSmell
Enfim,
como ainda estamos nos acostumando à orientação a objetos, aos poucos,
não se sinta reprimido ao usar um Switch, mas saiba que as pessoas vão
ficar sacaneando você depois!
Ahh
sim, claro, caso você opte em usá-lo indiscriminadamente, não conta pra
ninguém que fui eu que te mostrei o código dele... ok?!
Incrementos e decrementos da linguagem Java
São
chamados incrementos os comandos abreviados que o Java nos oferece para
acrescentar 1 no valor de uma variável. Esse tipo de sintaxe é muito
utilizada por exigir do programador preguiçoso (que nem eu) uma
quantidade menor de dígitos que o padrão comum de incrementação.
Ou seja, a sintaxe comum
i = i + 1;
pode ser reduzida simplesmente para
i++;
De forma semelhante, existe o decremento que permite retirar 1 do valor da variável.
i = i - 1; é equivalente à i--;
Além desses recursos, existe ainda as possibilidades destacadas abaixo:
/*
Opções de uso do incremento e decremento.
*/
int var = 0;
var++; // é equivalente a var = var + 1; Esse já vimos né!
var--; // é equivalente a var = var - 1; Esse também...
var+=2; // é equivalente a var = var + 2;
var*=2; // é equivalente a var = var * 2;
var/=2; // é equivalente a var = var / 2;
var-=1; // é equivalente a var = var - 1;
/*
O comando MOD (resto da divisão) é possível com a sintaxe %
*/
System.out.println( var % 2 );
Assim, podemos aproveitar a facilidade que o Java nos oferece e utilizar essas opções reduzidas.

Vamos lá...
É importante entender que ambas as sintaxes (i++ e ++i) incrementam em 1 o valor da variável i.
Mas existe diferença entre elas! Quando usamos o comando i++, os outros
trechos de código associados a esse comando serão executados antes que o
i seja incrementado.
Ou seja, imagine que exista uma classe Carro com um método acelerar() que recebe como parâmetro um inteiro. Agora veja o código abaixo:
Carro fusca = new Carro();
int vel = 10;
fusca.acelerar( vel++ );
Nesse caso, qual valor será passado para o método acelerar()?

Nãããããoooooooo!!!!!
Essa é a diferença. Veja que ao colocarmos i++, primeiro o valor atual da variável vel é passado para o método acelerar(), o método executa seu comportamento, o fluxo de execução volta para a chamada do método e, por fim, a variável vel é incrementada em 1. Se ao invés de i++ tivéssemos utilizado ++i, primeiro a variável vel seria incrementada, para depois seu valor ser passado para o método acelerar().

Bom, enfim, já sabemos então que deve-se atentar na escolha entre o pré-incremento (++i) e o pós-incremento (i++) para que você não sofra na busca pelo erro no código mais tarde.
Essa mesma regra é válida para o uso do --i e i--.
Estrutura de Repetição FOR
Muitas
linguagens oferecem comandos apropriados para se criar estruturas de
repetição do tipo FOR, mas tanto o C/C++, o Java e outras linguagens
similares definem essa estrutura num formato privilegiado.

É
o seguinte: no Java, além de definirmos o valor inicial e final do
índice dessa estrutura, podemos definir a forma como o índice é
incrementado a cada iteração!

É
verdade! Já estamos falando de incrementar o índice, de iterações, mas
ainda não falamos do objetivo principal da estrutura de repetição FOR.
Tenho quase certeza que você, leitor, deve estar achando um saco essa
explicação ridícula de “o que é um índice”, mas tenha paciência, pois
esse curso almeja transformar todos vocês em programadores Java. Não
posso excluir uma eventual clientela que por acaso não conheça
estruturas de repetição de linguagem de programação. Existe vida além da área de informática!

Bom,
voltando ao assunto! A estrutura de repetição FOR permite que o
programador repita trechos dos código várias vezes, sendo que em cada
iteração (vez de repetição) um índice de controle tem seu valor
alterado. Quando esse índice atinge um limite definido pelo programador,
as repetições terminam e o fluxo do programa retorna logo abaixo do
FOR.
Vamos a um exemplo de looping.
for (int i = 0; i < 10; i++) {
System.out.println( i );
}
Esse trecho de código imprimirá na tela do prompt todos os valores da variável i, que inicia em 0 e termina em 9. O primeiro elemento do comando (int i = 0; i < 10; i++) indica a variável que será utilizada como índice e seu valor inicial. O segundo elemento (int i = 0; i < 10; i++) mostra
até quando esse índice poderá variar - nesse caso, o looping é repetido
enquanto o índice for menor que 10 (ou seja, de 0 até 9). Por fim, o
último elemento do comando (int i = 0; i < 10; i++) mostra como o índice será incrementado. Ao invés do pós-incremento, poderíamos utilizar algo como i=i+2, ou ainda i=i*5, etc.
Estrutura de repetição WHILE
Além do FOR, existe também a estrutura de repetição WHILE. Antes da explicação, veja o código.
int i = 0;
while ( i < 10 ) {
System.out.println( i );
i++;
}
O
WHILE também permite a execução de loopings, porém ele simplesmente
testa se a condição passada no parâmetro é ou não verdadeira. Enquanto a
condição for verdadeira, continuará ocorrendo iterações. Veja que neste
caso é muito importante que você defina, dentro do escopo do WHILE, uma
forma de alterar o valor das variáveis envolvidas na condição, caso
contrário, o programa entrará em looping infinito - o que no Java, vai
gerar uma Exception (que veremos mais à frete).
Observe
ainda que, caso a condição de repetição não seja satisfeita logo na
primeira iteração, o fluxo não entrará no WHILE nenhuma vez. Veja o
código abaixo.
int z = 5;
while ( z < 3 ) {
System.out.println( z );
z++;
}
Aqui, como z já é iniciado com 5 e a condição exige que o valor de z seja menor que 3, o looping não chega a ser executado nenhuma vez.

Estrutura de repetição DO/WHILE
Como
vimos acima, em determinada situação o looping do WHILE pode não ser
executado nenhuma vez. Isso ocorre porque a condição sempre é verificada
no início do WHILE. Existe uma alternativa para isso quando se usa o
comando DO/WHILE. Ele possui funcionamento similar ao WHILE comum,
todavia sua condição será executada após a execução da iteração.
int j = 0;
do {
System.out.println( j );
j++;
} while ( j < 5 );
Nesse
caso, veja que sempre pelo menos uma execução do fluxo do DO/WHILE será
executada - mesmo que a condição não seja aceita. Isso ocorre
justamente porque a condição só é verificada no final.
Bom...
amigos, por hoje finalizamos o aprendizado. Como já foram mostrados
trechos separados de código durante esse paper, reservo-me no direito de
não criar um programa nessa aula. Acho que já foi suficiente por
enquanto!

Já que você pediu com tanto carinho, ai vai...
public class Exemplos {
public static void main(String args[]) {
// O comentário em Java pode ser definido com duas barras.
/*
* Ou ainda com barra e asterisco, sendo que neste caso,
* podem ocupar mais de uma linha.
*/
int a = 1;
int b = 2;
/*
* A estrutura lógica AND no Java é expresso com &&
*/
if ( a > 0 && b > 0 ) {
System.out.println( "Eu vou entrar aqui!" );
} else {
System.out.println( "Eu NÃO vou entrar aqui!" );
}
/*
* A estrutura lógica OR no Java é expresso com ||
*/
if ( a > 5 || b > 5 ) {
System.out.println( "Eu NÃO vou entrar aqui!" );
} else {
System.out.println( "Eu vou entrar aqui!" );
}
/*
* Podemos utilizar o comando Switch/Case para condições
* com mais de uma possibilidade. O Switch trabalha apenas
* com tipos primitivos byte, short, char, ou int.
* Caso não entre em nenhuma das opções, o Switch entrará
* na opção default.
*/
char c = 'z';
switch ( c ) {
case 'x': System.out.println( "Valor X" ); break;
case 'y': {
System.out.println( "Valor Y" );
} break;
case 'z': System.out.println( "Valor Z" ); break;
default: System.out.println( "Outras letras..." ); break;
}
/*
* O comando break evita a continuação dos casos quando
* uma das opções é selecionada. Neste exemplo, logo
* que selecionada a opção 2, todas as opções abaixo
* serão selecionadas, inclusive a default.
*/
short d = 2;
switch ( d ) {
case 1: System.out.println( "Valor 1" );
case 2: System.out.println( "Valor 2" );
case 3: System.out.println( "Valor 3" );
default: System.out.println( "Outros valores" );
}
/*
* Exemplo de arrays.
*/
int vetor1[] = new int[3];
vetor1[0] = 5;
vetor1[1] = 6;
vetor1[2] = 7;
int vetor2[] = new int[] { 1 , 2 , 3 };
int vetor3[] = { 1 , 2 , 3 };
/*
* Definição e leitura dos valores dos arrays.
* Aqui o valor do 3º item do vetor 1 será guardado
* no 2º item do vetor 3.
*/
vetor3[ 1 ] = vetor1[ 2 ];
/*
* Opções de uso do incremento e decremento.
*/
int var = 0;
var++; // é equivalente a var = var + 1;
var--; // é equivalente a var = var - 1;
var+=2; // é equivalente a var = var + 2;
var*=2; // é equivalente a var = var * 2;
var/=2; // é equivalente a var = var / 2;
var-=1; // é equivalente a var = var - 1;
/*
* O comando MOD (resto da divisão) é possível com a sintaxe %
*/
System.out.println( var % 2 );
/*
* Exemplo do uso do FOR
*/
for (int i = 0; i < vetor1.length; i++) {
System.out.println( "Valor do elemento " + i + " do vetor1: " + vetor1[i] );
}
/*
* Exemplo do uso do WHILE
*/
int i = 0;
while ( i < vetor2.length ) {
System.out.println( "Valor do elemento " + i + " do vetor2: " + vetor2[i] );
i++;
}
/*
* Exemplo do uso do DO/WHILE
*/
int j = 0;
do {
System.out.println( "Valor do elemento " + j + " do vetor3: " + vetor3[j] );
j++;
} while ( j < vetor3.length );
}
}
Bom... caros amigos. Por enquanto ficamos por aqui!
Nota
aos alunos presenciais: chegamos a estudar Arrays na aula 7, mas como
esse paper ficou extenso, optei em documentar esse conteúdo no próximo
material (aula 8).
Obrigado pela companhia.
Abraços, Guilherme Pontes
Nenhum comentário:
Postar um comentário